Docker实现Mysql8主从配置
[注:运行环境为centos 7]
1 使用docker下载mysql镜像,默认下载最mysql最新版本,目前版本号为8.0.13,如果需要其他版本请登录https://hub.docker.com/进行搜索
[root@localhost ~]# docker pull mysql
2 下载完毕后分别在创建/home/docker/mysql/mysql-3306-data、mysql-3307-data 这五个文件夹,其中mysql-3306-data、mysql-3307-data这两个文件夹用来保存mysql数据,否则docker rmi 镜像id/镜像name 都会删除mysql数据
[root@localhost ~]# cd /home
[root@localhost home]# mkdir docker
[root@localhost home]# cd docker
[root@localhost docker]# mkdir mysql
[root@localhost docker]# cd mysql
[root@localhost mysql]# mkdir mysql-3306-data
[root@localhost mysql]# mkdir mysql-3307-data
3 再创建mysql-3306.cnf、mysql-3307.cnf自定义mysql配置文件,用来配置mysql
[root@localhost mysql]# touch mysql-3306.cnf
[root@localhost mysql]# touch mysql-3307.cnf
4 编辑自定义mysql配置文件,复制下列代码
[注:本例只是简单配置,详细配置请搜索my.cnf详细配置,sql_mode值含义请看文章第二部分:sql_mode值的含义]
[注:server-id是唯一的,主从不能相同]
4.1 mysql-3306.cnf文件复制:
[mysqld]
datadir = /var/lib/mysql
server-id = 1
log-bin = mysql-bin
sql_mode=STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
4.1 mysql-3307.cnf文件复制:
[mysqld]
datadir = /var/lib/mysql
server-id = 2
log-bin = mysql-bin
sql_mode=STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
5 按Esc后,输入wq保存退出
6 启动mysql主从容器
[root@localhost mysql]# docker run --name mysql-3306 -v /home/docker/mysql/mysql-3306.cnf:/etc/mysql/my.cnf -v /home/docker/mysql/mysql-3306-data:/var/lib/mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql
[root@localhost mysql]# docker run --name mysql-3307 -v /home/docker/mysql/mysql-3307.cnf:/etc/mysql/my.cnf -v /home/docker/mysql/mysql-3307-data:/var/lib/mysql -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql
6.1 命令:-v /home/docker/mysql/mysql-3306.cnf:/etc/mysql/my.cnf 将宿主机自定义mysql-3306.cnf的mysql配置文件的内容,挂载到mysql容器执行/etc/mysql/my.cnf 配置文件中,如果不设置该命令,mysql容器无法加载我们自定义的mysql-3306.cnf配置文件中的内容
6.1.1 如果无法确定my.cnf的位置,可以去掉-v命令并启动:
[root@localhost mysql]# docker run --name mysql-3306 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql
启动容器,然后执行
[root@localhost mysql]# docker exec -it mysql-3306 /bin/bash
进入容器中,然后使用命令查询my.cnf的位置,
root@603b2ae769b1:/# find / -name '*.cnf'
/xxx/xxx/my.cnf
... ...
...
复制下来后执行
root@603b2ae769b1:/# exit
退出容器,然后执行
[root@localhost mysql]# docker stop mysql-3306
停止容器,最后执行
[root@localhost mysql]# docker rm -v mysql-3306
删除容器,并将复制下来的容器中的my.cnf路径加入到-v命令中
[root@localhost mysql]# docker run --name mysql-3306 -v /home/docker/mysql/mysql-3306.cnf:/xxx/xxx/my.cnf -v /home/docker/mysql/mysql-3306-data:/var/lib/mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql
命令中,重新执行启动
6.2 命令:-v /home/docker/mysql/mysql-3306-data:/var/lib/mysql 在自定义mysql配置文件中还指定了datadir = /var/lib/mysql,datadir表示数据存储目录的路径,我们也需要将数据存储目录的挂在到宿主机,这样就算执行 docker rm -v 容器id/容器name 也不会丢失数据库中的数据,如果不设置该命令,数据库中的数据会默认保存在mysql容器中的/var/lib/mysql目录下
7 设置权限、更新密码算法、便于使用Navicat连接,分别进入mysql主从容器中
[root@localhost mysql]# docker exec -it mysql-3306 /bin/bash
[root@localhost mysql]# docker exec -it mysql-3307 /bin/bash
[注:以下操作在mysql-3306容器、mysql-3307容器中完全相同,故只展示一遍,实操中需要执行两次]
7.1 输入账号密码
root@603b2ae769b1:/# mysql -u root -p
7.3 设置权限(为root分配权限,以便可以远程连接)
mysql> grant all PRIVILEGES on *.* to root@'%' WITH GRANT OPTION;
Query OK, 0 rows affected (0.01 sec)
7.4 由于Mysql5.6以上的版本修改了Password算法,这里需要更新密码算法,便于使用Navicat连接
16 注意,千万不要用navicat在mysql-3306从库中删除数据,否则从库mysql-3307报错,无法主从同步
sql_mode:
ONLY_FULL_GROUP_BY |
对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY中出现,那么将认为这个SQL是不合法的,因为列不在GROUP BY从句中 |
STRICT_TRANS_TABLES |
在该模式下,如果一个值不能插入到一个事务表中,则中断当前的操作,对非事务表不做任何限制 |
NO_ZERO_IN_DATE |
在严格模式,不接受月或日部分为0的日期。如果使用IGNORE选项,我们为类似的日期插入'0000-00-00'。在非严格模式,可以接受该日期,但会生成警告。 |
NO_ZERO_DATE |
在严格模式,不要将 '0000-00-00'做为合法日期。你仍然可以用IGNORE选项插入零日期。在非严格模式,可以接受该日期,但会生成警告 |
ERROR_FOR_DIVISION_BY_ZERO |
在严格模式,在INSERT或UPDATE过程中,如果被零除(或MOD(X,0)),则产生错误(否则为警告)。如果未给出该模式,被零除时MySQL返回NULL。如果用到INSERT IGNORE或UPDATE IGNORE中,MySQL生成被零除警告,但操作结果为NULL。 |
NO_AUTO_CREATE_USER |
防止GRANT自动创建新用户,除非还指定了密码。 |
NO_ENGINE_SUBSTITUTION |
如果需要的存储引擎被禁用或未编译,那么抛出错误。不设置此值时,用默认的存储引擎替代,并抛出一个异常。 |
mysql5.0以上版本支持三种sql_mode模式:
ANSI模式 |
宽松模式,对插入数据进行校验,如果不符合定义类型或长度,对数据类型调整或截断保存,报warning警告。 |
TRADITIONAL模式 |
严格模式,当向mysql数据库插入数据时,进行数据的严格校验,保证错误数据不能插入,报error错误。用于事物时,会进行事物的回滚。 |
STRICT_TRANS_TABLES模式 |
严格模式,进行数据的严格校验,错误数据不能插入,报error错误。 |
注意:自定义mysql配置文件中如果设置sql_mode=ONLY_FULL_GROUP_BY,则使用navicat执行sql时会报错:
Error Code: 1055. Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column '×××' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by