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]
[[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
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主從容器
[[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.cnf的mysql配置檔案的內容,掛載到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/mysql,datadir表示資料儲存目錄的路徑,我們也需要將資料儲存目錄的掛在到宿主機,這樣就算執行 docker rm -v 容器id/容器name 也不會丟失資料庫中的資料,如果不設定該命令,資料庫中的資料會預設儲存在mysql容器中的/var/lib/mysql目錄下
7 設定許可權、更新密碼演算法、便於使用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
8 使用navicat連線3306,3307
9 主庫mysql-3306上,查詢執行sql: SHOW MASTER STATUS ,並複製紅框中的值 mysql-bin.000006、2875
10 從庫 mysql- 3307上, 查詢執行 sql: STOP SLAVE , 停止slave
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;
[注: ,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
13 從庫 mysql- 3307上, 查詢執行 sql: SHOW SLAVE STATUS , 檢視slave狀態
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