1. 程式人生 > >PHP-Mysql 聯合做分表分庫操作詳解

PHP-Mysql 聯合做分表分庫操作詳解

一、當Mysql資料量過大時,就會面臨壓力分解,這時分庫分表是一個不錯的解決方案,現在我們就來談談Mysql如何分庫分表比較理想,然後再用php如何呼叫。
1,主從複製,讀寫分離
對主庫修改資料,查詢使用從庫。一主多從,來降低資料庫讀取壓力。         ①那麼什麼叫一主多從?             原理:   主資料庫只用來寫和更新操作,從資料庫用於查詢操作,實現主從複製,讀寫分離的目的;

               Master      主伺服器的    ip192.168.1.128 ;

                Slave1       從伺服器的    ip:192.168.1.129 ;

                Slave2       從伺服器的    ip:192.168.1.130 ;

                Slave3       從伺服器的    ip:192.168.1.131 ;

        mysql的複製(replication)是非同步複製,即從一個mysql實列或埠(稱之為Master)複製到另一個mysql實列的或埠(稱之為slave);複製操作由3個程序完成;

        其中2個(SQL程序和I/O程序)在Slave上,另一個在Master(binlog dump)上;

        要實現複製,必須開啟Master端的二進位制日誌(log-bin),log-bin記錄著整個資料對的操作資訊,所有slave從master端獲取該更新的日誌,將其傳送到本地並寫到本地檔案中,然後在讀取本地檔案內容執行日誌中記錄的更新操作;

        slave上已經完整拷貝master資料後,就可以連線到master上然後等待處理更新了.如果master當機或者slave連線斷開,slave會定期嘗試連線到master上直到能重連並且等待更新.重試的時間間隔由--master-connect-retry選項來控制,它的預設值是60秒;

        每個slave都記錄了它關閉時的日誌位置.msater是不知道有多少個slave連線上來或者哪個slave從什麼時候開始更新;

        注:啟用同步後,所有要同步的更新操作都必須在master上執行.否則,必須注意不要造成使用者在master上的更新和在slave上的更新引起衝突;

        ②、如何進行配置一主多從呢?

一. 實驗環境說明

10.0.0.101nd1.baby.localmysql master

10.0.0.102nd2.baby.localmysql slave

10.0.0.103nd3.baby.localmysql slave

1. 建立主從複製的帳號,為什麼不把賬戶的地址寫成”%”,這樣是為了安全著想,那個賬戶只能在指定的從伺服器上使用;

mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl103'@'10.0.0.103' IDENTIFIED BY 'yangcan';    

mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl102'@'10.0.0.102' IDENTIFIED BY 'yangcan';   

mysql> FLUSH PRIVILEGES;

2. 備份已有資料,並把資料複製到各從節點上;如果是空的資料,就跳過此步;

mysql> FLUSH TABLES WITH READ LOCK;

mysql> SHOW MASTER STATUS;

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

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |

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

| mysql-bin.000001 |      106 | test         |                  |

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

[[email protected] ~]# tar zcvf /tmp/mysql_fullbak.tar.gz /var/lib/mysql/

[[email protected] ~]# rsync -zrvz --delete /tmp/mysql_fullbak.tar.gz nd2.baby.local:/tmp/

[[email protected] ~]# rsync -zrvz --delete /tmp/mysql_fullbak.tar.gz nd3.baby.local:/tmp/

3. 解鎖讀

mysql> UNLOCK TABLES;

Query OK, 0 rows affected (0.00 sec)

4. 配置主伺服器:修改mysql master 10.0.0.101 的主配檔案;

[[email protected] ~]# vi /etc/my.cnf 

[mysqld]

datadir=/var/lib/mysql

socket=/var/lib/mysql/mysql.sock

user=mysql

# Disabling symbolic-links is recommended to prevent assorted security risks

symbolic-links=0

#### Master ####

server-id                = 1

log-bin                  = mysql-bin

log-bin-index           = mysql-bin.index

relay-log               = mysql-relay

relay-log-index        = mysql-relay.index

expire-logs-days        = 10

max-binlog-size         = 100M

log-slave-updates       = 1

binlog-do-db            = test

replicate-do-db         = test

binlog-ignore-db        = mysql

replicate-ignore-db     = mysql

引數解釋

server-id=1表示是本機的序號為1,一般來講就是master的意思

log-bin表示開啟binlog,開啟該選項才可以通過I/O寫到Slaverelay-log,也是可以進行replication的前提

binlog-do-db=test表示需要備份的資料庫test這個資料庫

log-slave-updates= 1從前一臺機器上同步過來的資料才能同步到下一臺機器 

replicate-do-db=test 表示同步test資料庫

如果需要備份多個數據庫,那麼應該寫多行

binlog-do-db=test1

binlog-do-db=test2

replicate-do-db=test1

replicate-do-db=test2

重啟服務

[[email protected] ~]# /etc/init.d/mysqld restart

5. 修改從伺服器: 10.0.0.102 和 10.0.0.103 的配置檔案,新增server-id = 2 或者 3;並分別重啟服務;

10.0.0.102:

[root@nd3 ~]# vi /etc/my.cnf 

[mysqld]

datadir=/var/lib/mysql

socket=/var/lib/mysql/mysql.sock

user=mysql

# Disabling symbolic-links is recommended to prevent assorted security risks

symbolic-links=0

server-id               = 2

10.0.0.103:

[root@nd3 ~]# vi /etc/my.cnf 

[mysqld]

datadir=/var/lib/mysql

socket=/var/lib/mysql/mysql.sock

user=mysql

# Disabling symbolic-links is recommended to prevent assorted security risks

symbolic-links=0

server-id               = 3

6. 102 和 103上配置同步sql語句;這些語句也可以寫在配置檔案中,方面維護;

mysql> CHANGE MASTER TO

    ->   MASTER_HOST='10.0.0.101',

    ->   MASTER_USER='repl102',103 上面改成repl103

    ->   MASTER_PASSWORD='yangcan',

    ->   MASTER_PORT=3306,

    ->   MASTER_LOG_FILE='mysql-bin.000001',

    ->   MASTER_LOG_POS=106,

    ->   MASTER_CONNECT_RETRY=10;

Query OK, 0 rows affected (0.02 sec)

mysql> START SLAVE;

Query OK, 0 rows affected (0.00 sec)

mysql> SHOW SLAVE STATUS\G;

.......

             Slave_IO_Running: Yes

            Slave_SQL_Running: Yes

7. 檢視主的狀態

mysql> show master status;

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

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |

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

| mysql-bin.000001 |      106 | test         |                  |

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

1 row in set (0.00 sec)

主伺服器上開啟了2Binlog Dump程序,

mysql> SHOW PROCESSLIST;

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

| Id | User    | Host                 | db    | Command     | Time | State                                                          | Info             |

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

|  3 | root    | localhost            | mysql | Query       |    0 | NULL                                                           | SHOW PROCESSLIST |

| 34 | repl102 | nd2:57981            | NULL  | Binlog Dump | 1428 | Has sent all binlog to slave; waiting for binlog to be updated | NULL             |

| 71 | repl103 | nd3.baby.local:37984 | NULL  | Binlog Dump | 1043 | Has sent all binlog to slave; waiting for binlog to be updated | NULL             |

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

3 rows in set (0.00 sec)

8. 測試環節,在主10.0.0.101 test資料庫上新建,刪除資料,然後在從上同步檢視,是否和主同步;

a)在主上操作:

mysql> create table t1(id int);

mysql> show tables;

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

| Tables_in_test |

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

| t1             |

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

mysql> insert into t1 values(1);

b). 在從上檢視:

mysql> select * from test.t1;

+------+

| id   |

+------+

|    1 |

+------+


2,分庫分表
    根據實體業務來分庫,分表。如,根據資料的活躍性,根據使用者uid等。
3,MySQL不同儲存引擎區別
  InnoDB 用於資料完整性/寫效能要求比較高的應用. MyISAM 適合查詢應用。 二、分表是分散資料庫壓力的好方法,那麼如何進行分表?分表的規則是什麼?分表之後資料如何插入?資料又如何調取?。