likes
comments
collection
share

记一次基于docker的mysql主从结构配【踩】置【坑】

作者站长头像
站长
· 阅读数 55

我这两天正在跟着b站某docker教学视频学习,刚好讲到了mysql主从结构配置。我之前并没有配置这种结构的经验,对mysql的了解也不过是select语句的水平,所以配置起来相当挣扎,踩了不少坑。就跟大家分享一下这次遇到的坑。

这里主从数据库分别用mysql-master, mysql-slave命名。 首先启动mysql-master。3307是容器在宿主机的端口,3306是mysql在容器内部的端口。

$ docker run -p 3307:3306 --name mysql-master \
-v ~/docker/tmp/apps/mysql/mysql-master/log:/var/log/mysql \
-v ~/docker/tmp/apps/mysql/mysql-master/data:/var/lib/mysql \
-v ~/docker/tmp/apps/mysql/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=123456 -d mysql

很快这里出现了第一个坑。当我查看容器是否启动时,我发现容器启动失败了,查看错误信息如下。

mysqld: Can't read dir of '/etc/mysql/conf.d/' (OS errno 2 - No such file or directory)

错误信息很明了,mysql没有找到 /etc/mysql/conf.d/这个配置文件。在docker中启动mysql时,为了数据持久化,利用了卷(volume)这个概念。其中三个卷分别映射了日志,数据和配置。问题出在配置的目录。我们必须指定配置目录conf.d的位置。 更改如下成功启动mysql-master。

$ docker run -p 3307:3306 --name mysql-master \
-v ~/docker/tmp/apps/mysql/mysql-master/log:/var/log/mysql \
-v ~/docker/tmp/apps/mysql/mysql-master/data:/var/lib/mysql \
-v ~/docker/tmp/apps/mysql/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 -d mysql

接着配置my.cnf。其中内容我都是抄的教程的,就不放在这里了。

$ cd ~/docker/tmp/apps/mysql/mysql-master/conf 
$ vim my.cnf 

然后为了使my.cnf生效,必须重启mysql-master容器。重启后我们进入该容器,并且尝试运行sql语句,确保mysql正常工作。

$ docker restart mysql-master 
$ docker exec -it mysql-master /bin/bash 
bash-4.4# mysql -p 
... 
mysql> show databases;
+--------------------+
| Database | 
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.04 sec)

mysql确实在运行,这样我们就可以在主数据库上配置一个从(slave)用户了。 这里'slave'@'%'是用户名和host,123456是密码。

mysql> CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.07 sec)

mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
Query OK, 0 rows affected (0.02 sec)

这样mysql-master主数据库就基本配置好了。现在开始从数据库mysql-slave的配置。

$ docker run -p 3308:3306 --name mysql-slave \
-v ~/docker/tmp/apps/mysql/mysql-slave/log:/var/log/mysql \
-v ~/docker/tmp/apps/mysql/mysql-slave/data:/var/lib/mysql \
-v ~/docker/tmp/apps/mysql/mysql-slave/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 -d mysql

然后继续配置my.cnf并重启mysql-slave

$ cd ~/docker/tmp/apps/mysql/mysql-slave/conf
$ vim my.cnf
...
$ docker restart mysql-slave

现在大概应该配置从数据库了,不过我们先进入主数据库,看一下主从状态。

$ docker exec -it mysql-master /bin/bash
bash-4.4# mysql -p
Enter password:
mysql> show master status;
+-----------------------+----------+--------------+------------------+-------------------+
| File                  | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-----------------------+----------+--------------+------------------+-------------------+
| mall-mysql-bin.000001 |      711 |              | mysql            |                   |
+-----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql>

记住711这个数字,后面会用到。 现在进入从数据库mysql-slave并且进行主从配置。这里master_host应该是宿主机的ip地址,用户名,密码之前都提到过。master_port是主数据库mysql-master在主机上的端口。log file我不懂。log pos就是刚才说的711,查看主数据库的主从状态得到的。

$ docker exec -it mysql-slave bash
bash-4.4# mysql -p
Enter password:
...
mysql> change master to master_host='192.168.0.255',master_user='slave',master_password='123456',\
master_port=3307,master_log_file='mall-mysql-bin.000001',\
master_log_pos=711,master_connect_retry=30;

Query OK, 0 rows affected, 10 warnings (0.15 sec)

完成配置后尝试启动slave并且查看他的状态。

mysql> start slave;

Query OK, 0 rows affected, 1 warning (0.05 sec)

\


mysql> show slave status \G;

*************************** 1. row ***************************

               Slave_IO_State: Connecting to source

                  Master_Host: 192.168.0.255

                  Master_User: slave

                  Master_Port: 3307

                Connect_Retry: 30

              Master_Log_File: mall-mysql-bin.000001

          Read_Master_Log_Pos: 711

               Relay_Log_File: mall-mysql-relay-bin.000001

                Relay_Log_Pos: 4

        Relay_Master_Log_File: mall-mysql-bin.000001

             Slave_IO_Running: Connecting

            Slave_SQL_Running: Yes

这时如果主从数据库已经成功连接,那么Slave_IO_Running和Slave_SQL_Running的状态都必须是yes。这里一直显示connecting,显然第二个坑出现了。

error connecting to master 'slave@192.168.0.255:3307'

我查看了状态里的Last_IO_Error,方法如下。

mysql> show slave status \G;
...
Last_IO_Error: error connecting to master 'slave@192.168.0.255:3307' - retry-time: 30 retries: 1 message: Can't connect to MySQL server on '192.168.0.255:3307' (111)

所以是连接失败了,我当时就猜是不是主机ip或者端口搞错了。如下命令查看ip。

$ ifconfig | grep broadcast
	inet 192.168.0.95 netmask 0xffffff00 broadcast 192.168.0.255

所以我的主机ip地址是192.168.0.95!并不是192.168.0.255。 更改mysql-slave中的主数据库配置并重启slave。

mysql> change master to master_host='192.168.0.95',master_user='slave',master_password='123456',master_port=3307,master_log_file='mall-mysql-bin.000001',master

log_pos=711,master_connect_retry=30;

mysql> start slave;

Query OK, 0 rows affected, 1 warning (0.07 sec)

\


mysql> show slave status \G;
*************************** 1. row ***************************

             Slave_IO_Running: Connecting

            Slave_SQL_Running: Yes

Slave_IO_Running依然是connecting,还是没能成功启动。 好的,继续查看错误日志。

Last_IO_Error: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection

完整的错误信息如下。

Last_IO_Error: error connecting to master 'slave@192.168.0.95:3307' - retry-time: 30 retries: 1 message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection

错误变了!好的变化啊。所以这一次是验证信息时出错了。似乎是要求secure connection。 我看到这个错误的时候一头雾水,超出知识范畴,只能去google搜索这个错误。结果还真让我找到了解决办法。 这时我们要去主数据库,做一些slave用户信息的更改。注意,要去主数据库。

mysql> ALTER USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY '123456';

Query OK, 0 rows affected (0.02 sec)

这里的用户名必须是我们之前创建的那个。 现在再去从数据库mysql-slave那边,再次尝试启动slave。

mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.10 sec)

mysql> show slave status \G;
*************************** 1. row ***************************

             Slave_IO_Running: Yes

            Slave_SQL_Running: No

这回Slave_IO_Running终于yes了,然而Slave_SQL_Running变成了no!!怎么回事?错误信息如下。

Last_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction 'ANONYMOUS' at master log mall-mysql-bin.000001, end_log_pos 994.

里面提到了log pos 994,我之前配置的明明是711。我猜是这里出了问题,决定再次去查看主数据库的状态。

mysql> show master status;

+-----------------------+----------+--------------+------------------+-------------------+

| File                  | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+-----------------------+----------+--------------+------------------+-------------------+

| mall-mysql-bin.000001 |      994 |              | mysql            |                   |

+-----------------------+----------+--------------+------------------+-------------------+

1 row in set (0.00 sec)

好吧真的变成994了,那么从数据库mysql-slave这边的设置也必须跟着改。

mysql> change master to master_host='192.168.0.95',master_user='slave',master_password='123456',master_port=3307,master_log_file='mall-mysql-bin.000001',master_log_pos=994, master_connect_retry=30;

Query OK, 0 rows affected, 10 warnings (0.09 sec)

mysql> start slave;
            Slave_IO_Running: Yes

            Slave_SQL_Running: Yes

终于啊!! 下面验证一下主从结构搭建成功。到主数据库里添加一个数据,看看能不能在从数据库那边查到。

mysql> create database db01;
Query OK, 1 row affected (0.04 sec)
mysql> use db01
Database changed
mysql> create table t1(id int, name varchar(20));
Query OK, 0 rows affected (0.10 sec)
mysql> insert into t1 values (10, 'scott');
Query OK, 1 row affected (0.03 sec)
mysql> select * from t1;
+------+-------+

| id   | name  |

+------+-------+

|   10 | scott |

+------+-------+

1 row in set (0.00 sec)

最后到从数据库这边。

mysql> use db01;

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A
Database changed

mysql> select * from t1;

+------+-------+

| id   | name  |

+------+-------+

|   10 | scott |

+------+-------+

1 row in set (0.00 sec)
mysql>

出现了同样的数据!终于配置成功了! 总结一下就是英文必须好。然后遇到错误不要慌,慢慢找原因。 中英文混合编辑文章好麻烦。

转载自:https://juejin.cn/post/7141905306992246821
评论
请登录