基于Docker实现MySQL8主从复制
banner 2023-03-06 11:05:24 gitlab
# 基于Docker产生两个MySQL实例
# docker-compose.yml
version: '3'
services:
mysql-master:
container_name: mysql-master
image: mysql
restart: always
ports:
- 3340:3306
privileged: true
volumes:
- $PWD/mysql-master/log:/var/log/mysql
- $PWD/mysql-master/conf/my.cnf:/etc/mysql/my.cnf
- $PWD/mysql-master/data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: "123456"
command: [
'--character-set-server=utf8mb4',
'--collation-server=utf8mb4_general_ci',
'--max_connections=3000'
]
networks:
- mysqlMS
mysql-slave:
container_name: mysql-slave
image: mysql
restart: always
ports:
- 3341:3306
privileged: true
volumes:
- $PWD/mysql-slave/log:/var/log/mysql
- $PWD/mysql-slave/conf/my.cnf:/etc/mysql/my.cnf
- $PWD/mysql-slave/data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: "123456"
command: [
'--character-set-server=utf8mb4',
'--collation-server=utf8mb4_general_ci',
'--max_connections=3000'
]
networks:
- mysqlMS
networks:
mysqlMS:
driver: bridge
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# vim /mysql-master/conf/my.cnf
[mysqld]
# [必须]服务器唯一ID,默认是1,一般取IP最后一段
server-id=1
# [必须]启用二进制日志
log-bin=mysql-bin
# 复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步)
binlog-ignore-db=mysql
# 设置需要同步的数据库 binlog_do_db = 数据库名;
# 如果是多个同步库,就以此格式另写几行即可。
# 如果不指明对某个具体库同步,表示同步所有库。除了binlog-ignore-db设置的忽略的库
# binlog_do_db = test #需要同步test数据库。
# 确保binlog日志写入后与硬盘同步
sync_binlog = 1
# 跳过所有的错误,继续执行复制操作
slave-skip-errors = all
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# vim /mysql-slave/conf/my.cnf
[mysqld]
# [必须]服务器唯一ID,默认是1,一般取IP最后一段
server-id=2
# 如果想实现 主-从(主)-从 这样的链条式结构,需要设置:
# log-slave-updates 只有加上它,从前一台机器上同步过来的数据才能同步到下一台机器。
# 设置需要同步的数据库,主服务器上不限定数据库,在从服务器上限定replicate-do-db = 数据库名;
# 如果不指明同步哪些库,就去掉这行,表示所有库的同步(除了ignore忽略的库)。
# replicate-do-db = test;
# 不同步test数据库 可以写多个例如 binlog-ignore-db = mysql,information_schema
replicate-ignore-db=mysql
## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
log-bin=mysql-bin
log-bin-index=mysql-bin.index
## relay_log配置中继日志
#relay_log=edu-mysql-relay-bin
## 还可以设置一个log保存周期:
#expire_logs_days=14
# 跳过所有的错误,继续执行复制操作
slave-skip-errors = all
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
温馨提示:
在主服务器上最重要的二进制日志设置是 sync_binlog,这使得mysql在每次提交事务的时候把二进制日志的内容同步到磁盘上,即使服务器崩溃也会把事件写入日志中。 sync_binlog这个参数是对于MySQL系统来说是至关重要的,他不仅影响到Binlog对MySQL所带来的性能损耗,而且还影响到MySQL中数据的完整性。
对于"sync_binlog"
参数的各种设置的说明如下:
- sync_binlog=0,当事务提交之后,MySQL不做fsync之类的磁盘同步指令刷新binlog_cache中的信息到磁盘,而让Filesystem自行决定什么时候来做同步,或者cache满了之后才同步到磁盘。
- sync_binlog=n,当每进行n次事务提交之后,MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘。 在MySQL中系统默认的设置是sync_binlog=0,也就是不做任何强制性的磁盘刷新指令,这时候的性能是最好的,但是风险也是最大的。因为一旦系统Crash,在binlog_cache中的所有binlog信息都会被丢失。
- 而当设置为 sync_binlog=1 的时候,是最安全但是性能损耗最大的设置。因为当设置为1的时候,即使系统Crash,也最多丢失binlog_cache中未完成的一个事务,对实际数据没有任何实质性影响。
# docker-compose up -d
# 获取两个实例的IP
docker network inspect mysql-master-slave_mysqlMS
1
[
{
"Name": "mysql-master-slave_mysqlMS",
"Id": "ce1cb9bc74e5676c9ff7aebe2d89f7d72c6f235780e434a9ee47d4d5b8a5e534",
"Created": "2022-10-05T17:33:17.511158672Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
...
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"6de7e22742e34d73d385d4ab864690d25de6da5db7876f55a43562da6bc51656": {
"Name": "mysql-master",
"EndpointID": "720e04502895a57bab545c136ac8a83008838337f2b2cdaafc5f3dbd1e59121d",
"MacAddress": "02:42:ac:13:00:03",
"IPv4Address": "172.19.0.3/16",
"IPv6Address": ""
},
"eb1e7259d395d7c4b0ca502c70643647faf35af3987ec0621fea566fab972d29": {
"Name": "mysql-slave",
"EndpointID": "b3f6599da5d7fe08b016ac146e6d0bd9cbb501ca98c348701d93ea899324fcbf",
"MacAddress": "02:42:ac:13:00:02",
"IPv4Address": "172.19.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {
"com.docker.compose.network": "mysqlMS",
"com.docker.compose.project": "mysql-master-slave",
"com.docker.compose.version": "2.10.2"
}
}
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
mysql-master:172.19.0.3
mysql-slave:172.19.0.2
# 进入主mysql服务
docker exec -it mysql-master bash
mysql -uroot -p123456
# 查看server_id 是否生效
mysql> show variables like '%server_id%';
+----------------+-------+
| Variable_name | Value |
+----------------+-------+
| server_id | 1 |
| server_id_bits | 32 |
+----------------+-------+
2 rows in set (0.03 sec)
# 查看 master 信息 File 和 Position 从服务上会使用到
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 2351 | | mysql | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.01 sec)
# 创建一个用户,用户备份
mysql> create user 'slave'@'%' identified with mysql_native_password by '123456';
mysql> grant replication slave,replication client on *.* to 'slave'@'%';
mysql> flush privileges;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 进入从slave服务
docker exec -it mysql-slave bash
mysql -uroot -p123456
# 查看server_id 是否生效
mysql> show variables like '%server_id%';
+----------------+-------+
| Variable_name | Value |
+----------------+-------+
| server_id | 2 |
| server_id_bits | 32 |
+----------------+-------+
2 rows in set (0.02 sec)
# 连接主mysql服务 master_log_file 和 master_log_pos的值要填写主master里查出来的值
change master to master_host='172.19.0.3',master_user='slave',master_password='123456',master_port=3306,master_log_file='mysql-bin.000001', master_log_pos=2351,master_connect_retry=30;
# 启动slave
mysql> start slave;
# 查看状态
mysql> show slave status \G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: 172.19.0.3
Master_User: slave
Master_Port: 3306
Connect_Retry: 30
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 2351
Relay_Log_File: eb1e7259d395-relay-bin.000002
Relay_Log_Pos: 2520
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB: mysql
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 2351
Relay_Log_Space: 2737
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: 22da853f-44d3-11ed-ba2a-0242ac120002
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
1 row in set, 1 warning (0.01 sec)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
连接主mysql参数说明:
master_port:Master的端口号,指的是容器的端口号
master_user:用于数据同步的用户
master_password:用于同步的用户的密码
master_log_file:指定 Slave 从哪个日志文件开始复制数据,即上文中提到的 File 字段的值
master_log_pos:从哪个 Position 开始读,即上文中提到的 Position 字段的值
master_connect_retry:如果连接失败,重试的时间间隔,单位是秒,默认是60秒
# 设置从服务器slave为只读模式
# 查看只读状态
SHOW VARIABLES LIKE '%read_only%';
# super权限的用户只读状态 1.只读 0:可写
SET GLOBAL super_read_only=1;
# 普通权限用户读状态 1.只读 0:可写
SET GLOBAL read_only=1;
1
2
3
4
5
6
2
3
4
5
6
https://www.cnblogs.com/haima/p/14341903.html
https://www.cnblogs.com/wade-lt/p/9008058.html
https://www.cnblogs.com/kevingrace/p/6261111.html