mycat+mysql搭建高可用集群1--垂直分庫


mycat垂直分庫

本文主要介紹了如何使用mycat對mysql數據庫進行垂直分庫,包括:

  • 垂直分庫的步驟
  • 垂直分庫的環境准備
  • 配置mycat垂直分庫

 

1. 垂直分庫的步驟

  1. 收集分析業務模塊間的關系
  2. 復制數據庫到其他實例(減輕業務影響
  3. 配置mycat垂直分庫
  4. 通過mycat訪問DB
  5. 刪除原庫中已遷移表

 

2. 垂直分庫的環境准備

假定:node1主機為mysql數據庫服務器,有dolphin_db數據庫,訪問壓力大,要進行垂直分庫。即將該數據庫分為order_db,product_db,customer_db。

主機名 IP 角色 數據庫 部署軟件及版本
node1 172.31.11.134 mycat mysql dolphin_db mysql-5.7 mycat-1.6.7.3 xtrabackup-2.4.12
node2 172.31.11.135 mysql order_db mysql-5.7 xtrabackup-2.4.12
node3 172.31.11.136 mysql product_db mysql-5.7 xtrabackup-2.4.12
node4 172.31.11.138 mysql customer_db mysql-5.7 xtrabackup-2.4.12

 

2.1 node1備份

1. 進行物理備份

[root@node1 ~]# innobackupex --defaults-file=/data/mysql/my.cnf --user=root --password=abcd@1234 --socket=/data/mysql/run/mysql.sock /data/backup

2. 將備份文件復制到node2-4

[root@node1 ~]# scp -r /data/backup/2019-10-18_09-42-25/ node2:/data/backup/

[root@node1 ~]# scp -r /data/backup/2019-10-18_09-42-25/ node3:/data/backup/

[root@node1 ~]# scp -r /data/backup/2019-10-18_09-42-25/ node4:/data/backup/

3.創建復制用戶

mysql> grant replication slave on *.* to repluser@'172.31.11.%' identified by 'replpass';

2.2 node2還原

1. 准備一個備份

innobackupex --defaults-file=/data/mysql/my.cnf --socket=/data/mysql/run/mysql.sock --user=root --password='abcd@1234'  --apply-log /data/backup/2019-10-18_09-42-25

2. 恢復數據前需要清空/data/mysql/data(數據目錄)和cd /data/mysql/log/iblog(innodb日志目錄)的內容,否則報錯

rm -rf /data/mysql/data/*

rm -rf /data/mysql/log/iblog/*

3. 恢復數據

innobackupex --defaults-file=/data/mysql/my.cnf --user=root --password --socket=/data/mysql/run/mysql.sock --copy-back /data/backup/2019-10-18_09-42-25

4. 修改目錄權限

chown -R mysql:mysql /data/mysql

5. 重啟mysqld服務

/usr/local/mysql/bin/mysqld_safe --defaults-file=/data/mysql/my.cnf --user=mysql &

6. 由於恢復過來的數據庫時dolphin_db,需要將其改為order_db,由於不能直接修改數據庫名稱,可通過修改表名的方式間接修改。

 

修改數據庫名稱腳本

  [root@node2 ~]# cat rename.sh

#!/bin/bash

#作者:fafu_li

#時間:2015.08.10

#mysql數據庫改名,官方沒有直接修改數據庫名稱的命令

#只有通過修改表名方式實現

source /etc/profile        #加載系統環境變量

source ~/.bash_profile    #加載用戶環境變量

set -o nounset             #引用未初始化變量時退出

mysqlconn="mysql -hlocalhost -uroot -pabcd@1234"

#需要修改的數據庫名

olddb="dolphin_db"

#修改后的數據庫名

newdb="order_db"

#創建新數據庫

$mysqlconn -e "drop database if exists ${newdb};create database ${newdb};"

#獲取所有表名

tables=$($mysqlconn -N -e "select table_name from information_schema.tables where table_schema='${olddb}'")

#修改表名

for name in $tables;do

    $mysqlconn -e "rename table ${olddb}.${name} to ${newdb}.${name}"

done

#刪除老的空庫

$mysqlconn -e "drop database ${olddb}"

7. 重置二進制日志

mysql> reset master;

8. 連接至主服務器,配置主從復制

mysql> change master to master_host='172.31.11.134', master_user='repluser', master_password = 'replpass', master_auto_position=1;

9. 由於主從復制過程中可以使主從數據庫的名稱不一致(node1:dolphin_db,node2:order_db)

mysql> change replication filter replicate_rewrite_db=((dolphin_db, order_db));

10. 開啟復制

mysql> start slave;

node3node4都執行和node2相同的操作,只是數據庫名稱為:product_dbcustomer_db

 

3. 配置mycat垂直分庫  

1. 需要修改的配置文件介紹

  • 使用schema.xml配置邏輯庫、
  • 使用server.xml配置系統變量及用戶權限
  • 由於沒有用到水平分片,不需要配置rule.xml

2. 配置schema.xml,配置邏輯庫

 1 <?xml version="1.0"?>
 2 <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
 3 <mycat:schema xmlns:mycat="http://io.mycat/">
 4         <schema name="dolphin_db" checkSQLschema="false" sqlMaxLimit="100">
 5            <table name="order_master" primaryKey="order_id" dataNode="ordb"/>
 6            <table name="order_detail" primaryKey="order_detail_id" dataNode="ordb"/>
 7            <table name="order_customer_addr" primaryKey="customer_addr_id" dataNode="ordb"/>
 8            <table name="order_cart" primaryKey="cart_id" dataNode="ordb"/>
 9            <table name="region_info" primaryKey="region_id" dataNode="ordb"/>
10            <table name="shipping_info" primaryKey="ship_id" dataNode="ordb"/>
11            <table name="warehouse_info" primaryKey="w_id" dataNode="ordb"/>
12            <table name="warehouse_proudct" primaryKey="wp_id" dataNode="ordb"/>
13 
14           
15            <table name="product_brand_info" primaryKey="brand_id" dataNode="prodb"/>
16            <table name="product_category" primaryKey="category_id" dataNode="prodb"/>
17            <table name="product_comment" primaryKey="comment_id" dataNode="prodb"/>
18            <table name="product_info" primaryKey="product_id" dataNode="prodb"/>
19            <table name="product_pic_info" primaryKey="product_pic_id" dataNode="prodb"/>
20            <table name="product_supplier_info" primaryKey="supplier_id" dataNode="prodb"/>
21 
22 
23            <table name="customer_balance_log" primaryKey="balance_id" dataNode="custdb"/>
24            <table name="customer_inf" primaryKey="customer_inf_id" dataNode="custdb"/>
25            <table name="customer_level_inf" primaryKey="customer_level" dataNode="custdb"/>
26            <table name="customer_login" primaryKey="customer_id" dataNode="custdb"/>
27            <table name="customer_login_log" primaryKey="login_id" dataNode="custdb"/>
28            <table name="customer_point_log" primaryKey="point_id" dataNode="custdb"/>
29         </schema>
30 
31 
32         <dataNode name="ordb" dataHost="node2" database="order_db" />
33         <dataNode name="prodb" dataHost="node3" database="product_db" />
34         <dataNode name="custdb" dataHost="node4" database="customer_db" />
35 
36 
37         <dataHost name="node2" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
38                 <heartbeat>select user()</heartbeat>
39                 <writeHost host="172.31.11.135" url="172.31.11.135:3306" user="mycat" password="mycat"></writeHost>
40         </dataHost>
41 
42         <dataHost name="node3" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
43                 <heartbeat>select user()</heartbeat>
44                 <writeHost host="172.31.11.136" url="172.31.11.136:3306" user="mycat" password="mycat"></writeHost>
45         </dataHost>
46 
47         <dataHost name="node4" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
48                 <heartbeat>select user()</heartbeat>
49                 <writeHost host="172.31.11.138" url="172.31.11.138:3306" user="mycat" password="mycat"></writeHost>
50         </dataHost>
51 
52 </mycat:schema>

注意:由於mycat在和node2 node3 node4節點的mysql通信時,使用的是mycat用戶,密碼是mycat。因此我們需要在node2 node3 node4中分別創建該用戶並授權

mysql> grant select, insert, update, delete, execute on *.* to 'mycat'@'172.31.11.%' identified by 'mycat';

3. 配置server.xml,添加用戶,讓其可訪問該邏輯庫

1 <user name="dolphin" defaultAccount="true">
2             <property name="usingDecrypt">1</property>
3             <property name="password">PtBAuXp5Fi0b8riGxcG5SFzxqRHGVLD/bcXi+66Q/tppwZxy2P2DnhNm0mj+8u1JGyW/bLvqSXMDlntRy+n3ig==</property>
4             <property name="schemas">dolphin_db</property>
5 </user>    

  注意:這里對password進行了加密,方法如下:

[root@node1 ~]# cd /usr/local/mycat/lib
[root@node1 lib]# java -cp Mycat-server-1.6.7.3-release.jar io.mycat.util.DecryptUtil 0:dolphin:dolphin 

4. 通過mycat連接數據庫

[root@node1 bin]# ./mycat start

發現90668066端口已經開啟,則說明mycat已經啟動成功。

5. 通過8066端口,訪問邏輯數據庫dolphin_db

 

[root@node1 bin]# mysql -udolphin -p -P8066 -h127.0.0.1
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.29-mycat-1.6.7.3-release-20190927161129 MyCat Server (OpenCloudDB)

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+------------+
| DATABASE   |
+------------+
| dolphin_db |
+------------+
1 row in set (0.01 sec)

mysql> use dolphin_db
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> show tables;
+-----------------------+
| Tables in dolphin_db  |
+-----------------------+
| customer_balance_log  |
| customer_inf          |
| customer_level_inf    |
| customer_login        |
| customer_login_log    |
| customer_point_log    |
| order_cart            |
| order_customer_addr   |
| order_detail          |
| order_master          |
| product_brand_info    |
| product_category      |
| product_comment       |
| product_info          |
| product_pic_info      |
| product_supplier_info |
| region_info           |
| shipping_info         |
| warehouse_info        |
| warehouse_proudct     |
+-----------------------+
20 rows in set (0.00 sec)

6. 取消 node2 node3 node4 node1的主從復制關系,順便刪除node2 node3 node4中多余的表。

 

node2:

       mysql> stop slave;

mysql> reset slave all;

將多余的表都drop掉。

node3node4上的操作同理。

 

4. 配置和應用全局表

mysql> select supplier_name, b.region_name as '', c.region_name as '', d.region_name as '' from product_supplier_info a join region_info b on b.region_id = a.province join region_info c on c.region_id = a.city join region_info d on d.region_id = a.district;

ERROR 1064 (HY000): invalid route in sql, multi tables found but datanode has no intersection  sql:select supplier_name, b.region_name as '', c.region_name as '', d.region_name as '' from product_supplier_info a join region_info b on b.region_id = a.province join region_info c on c.region_id = a.city join region_info d on d.region_id = a.district

       由於表product_supplier_info位於node2上的product_db庫中,表region_info位於node1上的order_db庫中,兩個表並不位於同一物理庫中,因此當聯合查詢時會報錯。

       此外,region_info表在其他物理庫中也會使用到,因此可以考慮將region_info表定義為全局表。

 

 

4.1 配置步驟

1. region_info表備份,並在node3node4上各恢復一份

主機node2上:獲取建表語句

 

CREATE TABLE `region_info` (
  `region_id` smallint(6) NOT NULL AUTO_INCREMENT COMMENT '主鍵id',
  `parent_id` smallint(6) NOT NULL DEFAULT '0' COMMENT '上級地區id',
  `region_name` varchar(150) COLLATE utf8mb4_bin NOT NULL COMMENT '城市名稱',
  `region_level` tinyint(1) NOT NULL COMMENT '級別',
  PRIMARY KEY (`region_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='地區信息表';

 

主機node3上:

  • 創建表
CREATE TABLE `region_info` (
  `region_id` smallint(6) NOT NULL AUTO_INCREMENT COMMENT '主鍵id',
  `parent_id` smallint(6) NOT NULL DEFAULT '0' COMMENT '上級地區id',
 `region_name` varchar(150) COLLATE utf8mb4_bin NOT NULL COMMENT '城市名稱',
  `region_level` tinyint(1) NOT NULL COMMENT '級別',
 PRIMARY KEY (`region_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='地區信息表';
  • 刪除表空間,只剩表結構
mysql> ALTER TABLE region_info DISCARD TABLESPACE;
  • xtrabackup的全備中,找到這個文件復制過去
cp /data/backup/2019-10-18_09-42-25/dolphin_db/region_info.ibd /data/mysql/data/product_db/
chown mysql:mysql region_info.ibd
  • 導入表空間
mysql> ALTER TABLE region_info IMPORT TABLESPACE;

主機node4上的操作與node3相同。

2. 修改mycat的配置文件schema.xml中表region_info的配置

 

該行修改后為:

<table name="region_info" primaryKey="region_id" dataNode="ordb,prodb,custdb" type="global"/>

3. 重啟mycat服務

[root@node1 bin]# ./mycat stop
[root@node1 bin]# ./mycat start

4. 再運行上面的語句,發現沒有報錯。(由於數據不全,因此查詢為空)

mysql> select supplier_name, b.region_name as '', c.region_name as '', d.region_name as '' from product_supplier_info a join region_info b on b.region_id = a.province join region_info c on c.region_id = a.city join region_info d on d.region_id = a.district;

Empty set (1.76 sec)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM