1. 程式人生 > >Docker實現Mysql8主從配置

Docker實現Mysql8主從配置

Docker實現Mysql8主從配置

[注:執行環境為centos 7]

1 使用docker下載mysql映象,預設下載最mysql最新版本,目前版本號為8.0.13,如果需要其他版本請登入https://hub.docker.com/進行搜尋

[[email protected] ~]#  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資料

[[email protected] ~]# cd /home

[[email protected]  home]# mkdir docker

[[email protected]  home]# cd docker

[[email protected]  docker]# mkdir mysql

[[email protected]  docker]# cd mysql

[[email protected]

  mysql]# mkdir mysql-3306-data

[[email protected]  mysql]# mkdir mysql-3307-data


3 再建立mysql-3306.cnf、mysql-3307.cnf自定義mysql配置檔案,用來配置mysql

[[email protected]  mysql]touch mysql-3306.cnf

[[email protected]  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


按Esc後,輸入wq儲存退出


6 啟動mysql主從容器

[[email protected]  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


[[email protected]  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.cnfmysql配置檔案的內容,掛載到mysql容器/etc/mysql/my.cnf 配置檔案中,如果不設定該命令,mysql容器無法載入我們自定義的mysql-3306.cnf配置檔案中的內容


6.1.1 如果無法確定my.cnf的位置,可以去掉-v命令並啟動:

[[email protected]  mysql]docker run --name mysql-3306 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql

啟動容器,然後執行 

[[email protected]  mysql]docker exec -it mysql-3306 /bin/bash 

進入容器中,然後使用命令查詢my.cnf的位置,

[email protected]:/# find / -name '*.cnf' 

/xxx/xxx/my.cnf

... ...

...

複製下來後執行

[email protected]:/# exit

退出容器,然後執行 

[[email protected]  mysql]# docker stop mysql-3306 

停止容器,最後執行 

[[email protected]  mysql]docker rm -v mysql-3306  

刪除容器,並將複製下來的容器中的my.cnf路徑加入到-v命令中

[[email protected]  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/mysqldatadir表示資料儲存目錄的路徑,我們也需要將資料儲存目錄的掛在到宿主機,這樣就算執行 docker rm -v 容器id/容器name 也不會丟失資料庫中的資料,如果不設定該命令,資料庫中的資料會預設儲存在mysql容器中的/var/lib/mysql目錄下


設定許可權、更新密碼演算法、便於使用Navicat連線,分別進入mysql主從容器中

[[email protected]  mysql]docker exec -it mysql-3306 /bin/bash


[[email protected]  mysql]docker exec -it mysql-3307 /bin/bash


[注:以下操作在mysql-3306容器、mysql-3307容器中完全相同,故只展示一遍,實操中需要執行兩次]


7.1 輸入賬號密碼

[email protected]:/# mysql -u root -p 


7.3 設定許可權(為root分配許可權,以便可以遠端連線)

mysql> grant all PRIVILEGES on *.* to [email protected]'%' WITH GRANT OPTION;

Query OK, 0 rows affected (0.01 sec)


7.4 由於Mysql5.6以上的版本修改了Password演算法,這裡需要更新密碼演算法,便於使用Navicat連線

mysql> grant all PRIVILEGES on *.* to [email protected]'%' WITH GRANT OPTION; Query OK, 0 rows affected (0.01 sec)
mysql> ALTER user 'root'@'%' IDENTIFIED BY '123456' PASSWORD EXPIRE NEVER; Query OK, 0 rows affected (0.11 sec)
mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.01 sec)
7.5 執行完畢後退出mysql以及mysql容器 mysql> exit
[email protected]:/# exit

使用navicat連線3306,3307 972f445463e059d825fbbb55234990e48929b83d

主庫mysql-3306上,查詢執行sql:  SHOW MASTER STATUS ,並複製紅框中的值 mysql-bin.000006、2875 2a89f7962b1fd4d4eff503fdc1cb9db559cb2237

10 從庫 mysql- 3307上, 查詢執行 sql:  STOP SLAVE   , 停止slave 06487b68bc75bcaf9f354e177055e3d8337fbf34

11  配置主庫連線,使用root使用者, 從庫 mysql- 3307上, 查詢執行 sq l: CHANGE MASTER TO MASTER_HOST='192.168.43.188',MASTER_PORT=3306,MASTER_USER='root',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000006',MASTER_LOG_POS=2875; df4d5ce1c553643df18087e869df3e0ec4e5d323
[注: ,MASTER_LOG_FILE='mysql-bin.000006',MASTER_LOG_POS=2875; 要和主庫mysql-3306上面 SHOW MASTER STATUS, 複製紅框中的值 mysql-bin.000006、2875 的時候得到的值一致 ]

12  從庫 mysql- 3307上, 查詢執行 sql: START  SLAVE   , 停止slave 186963e7148a0f76933dac8599d9b9d18152a338

13  從庫 mysql- 3307上, 查詢執行 sql:  SHOW  SLAVE  STATUS , 檢視slave狀態 2a05cdf87cc4b96b1bbaf3428198e1d4a7382e40

14 配置完成,測試主從複製,在主庫mysql-3306上建立資料庫、表,看看是否mysql-3307也同步 3306上執行,主庫mysql-3306上查詢執行sql: CREATE DATABASE test DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
15 然後navicat上重新整理mysql-3307,發現mysql-3307上也建立有test庫了,說明主從同步成功,可以接著測試建立表、對錶的資料進行增刪改進行測試,主庫 mysql-3306上查詢執行sql:  CREATE TABLE `user` ( `id`  int NOT NULL AUTO_INCREMENT , `user_name`  varchar(50) NULL , PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci ;

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