1. 程式人生 > 程式設計 >Mysql 運維

Mysql 運維

環境:CentOS7

版本:mysql

1. 部署

本文僅介紹 rpm 安裝方式

1.1. 安裝 mysql yum 源

官方下載地址:https://dev.mysql.com/downloads/repo/yum/

(1)下載 yum 源

$ wget https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm複製程式碼

(2)安裝 yum repo 檔案並更新 yum 快取

$ rpm -ivh mysql80-community-release-el7-1.noarch.rpm複製程式碼

執行結果:

會在 /etc/yum.repos.d/ 目錄下生成兩個 repo 檔案

$ ls | grep mysql
mysql-community.repo
mysql-community-source.repo複製程式碼

更新 yum:

$ yum clean all
$ yum makecache複製程式碼

(3)檢視 rpm 安裝狀態

$ yum search mysql | grep server
mysql-community-common.i686 : MySQL database common files for server and client
mysql-community-common.x86_64 : MySQL database common files for server and
mysql-community-test.x86_64 : Test suite for the MySQL database server
                       : administering MySQL servers
mysql-community-server.x86_64 : A very fast and reliable SQL database server複製程式碼

通過 yum 安裝 mysql 有幾個重要目錄:

# 配置檔案
/etc/my.cnf
# 資料庫目錄
/var/lib/mysql/
# 配置檔案
/usr/share/mysql(mysql.server命令及配置檔案)
# 相關命令
/usr/bin(mysqladmin mysqldump等命令)
# 啟動指令碼
/usr/lib/systemd/system/mysqld.service (註冊為 systemd 服務)複製程式碼

(4)安裝 mysql 伺服器

$ yum install mysql-community-server複製程式碼

1.2. mysql 服務管理

通過 yum 方式安裝 mysql 後,本地會有一個名為 mysqld

的 systemd 服務。

其服務管理十分簡便:

# 檢視狀態
systemctl status mysqld
# 啟用服務
systemctl enable mysqld
# 禁用服務
systemctl disable mysqld
# 啟動服務
systemctl start mysqld
# 重啟服務
systemctl restart mysqld
# 停止服務
systemctl stop mysqld複製程式碼

1.3. 初始化資料庫密碼

檢視一下初始密碼

$ grep "password" /var/log/mysqld.log
2018-09-30T03:13:41.727736Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: %:lt+srWu4k1複製程式碼

執行命令:

mysql -uroot -p<臨時密碼>複製程式碼

輸入臨時密碼,進入 mysql,如果要修改密碼,執行以下指令:

ALTER user 'root'@'localhost' IDENTIFIED BY '你的密碼';複製程式碼

注:密碼強度預設為中等,大小寫字母、數字、特殊符號,只有修改成功後才能修改配置再設定更簡單的密碼

1.4. 配置遠端訪問

CREATE USER 'root'@'%' IDENTIFIED BY '你的密碼';
GRANT ALL ON *.* TO 'root'@'%';
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '你的密碼';
FLUSH PRIVILEGES;複製程式碼

1.5. 跳過登入認證

vim /etc/my.cnf複製程式碼

在 [mysqld] 下面加上 skip-grant-tables

作用是登入時跳過登入認證,換句話說就是 root 什麼密碼都可以登入進去。

執行 systemctl restart mysqld,重啟 mysql

2. 運維

2.1. 建立使用者

CREATE USER 'username'@'host' IDENTIFIED BY 'password';複製程式碼

說明:

  • username:你將建立的使用者名稱
  • host:指定該使用者在哪個主機上可以登陸,如果是本地使用者可用 localhost,如果想讓該使用者可以從任意遠端主機登陸,可以使用萬用字元%
  • password:該使用者的登陸密碼,密碼可以為空,如果為空則該使用者可以不需要密碼登陸伺服器

示例:

CREATE USER 'dog'@'localhost' IDENTIFIED BY '123456';
CREATE USER 'pig'@'192.168.1.101_' IDENDIFIED BY '123456';
CREATE USER 'pig'@'%' IDENTIFIED BY '123456';
CREATE USER 'pig'@'%' IDENTIFIED BY '';
CREATE USER 'pig'@'%';複製程式碼

2.2. 授權

命令:

GRANT privileges ON databasename.tablename TO 'username'@'host'複製程式碼

說明:

  • privileges:使用者的操作許可權,如SELECTINSERTUPDATE等,如果要授予所的許可權則使用ALL
  • databasename:資料庫名
  • tablename:表名,如果要授予該使用者對所有資料庫和表的相應操作許可權則可用*表示,如*.*

示例:

GRANT SELECT,INSERT ON test.user TO 'pig'@'%';
GRANT ALL ON *.* TO 'pig'@'%';
GRANT ALL ON maindataplus.* TO 'pig'@'%';複製程式碼

注意:

用以上命令授權的使用者不能給其它使用者授權,如果想讓該使用者可以授權,用以下命令:

GRANT privileges ON databasename.tablename TO 'username'@'host' WITH GRANT OPTION;複製程式碼

2.3. 撤銷授權

命令:

REVOKE privilege ON databasename.tablename FROM 'username'@'host';複製程式碼

說明:

privilege,databasename,tablename:同授權部分

例子:

REVOKE SELECT ON *.* FROM 'pig'@'%';複製程式碼

注意:

假如你在給使用者'pig'@'%'授權的時候是這樣的(或類似的):GRANT SELECT ON test.user TO 'pig'@'%',則在使用REVOKE SELECT ON *.* FROM 'pig'@'%';命令並不能撤銷該使用者對 test 資料庫中 user 表的SELECT 操作。相反,如果授權使用的是GRANT SELECT ON *.* TO 'pig'@'%';REVOKE SELECT ON test.user FROM 'pig'@'%';命令也不能撤銷該使用者對 test 資料庫中 user 表的Select許可權。

具體資訊可以用命令SHOW GRANTS FOR 'pig'@'%'; 檢視。

2.4. 更改使用者密碼

SET PASSWORD FOR 'username'@'host' = PASSWORD('newpassword');複製程式碼

如果是當前登陸使用者用:

SET PASSWORD = PASSWORD("newpassword");複製程式碼

示例:

SET PASSWORD FOR 'pig'@'%' = PASSWORD("123456");複製程式碼

2.5. 備份與恢復

Mysql 備份資料使用 mysqldump 命令。

mysqldump 將資料庫中的資料備份成一個文字檔案,表的結構和表中的資料將儲存在生成的文字檔案中。

備份:

2.5.1. 備份一個資料庫

語法:

mysqldump -u <username> -p <database> [<table1> <table2> ...] > backup.sql複製程式碼

  • username 資料庫使用者
  • dbname 資料庫名稱
  • table1 和 table2 引數表示需要備份的表的名稱,為空則整個資料庫備份;
  • BackupName.sql 引數表設計備份檔案的名稱,檔名前面可以加上一個絕對路徑。通常將資料庫被分成一個字尾名為 sql 的檔案

2.5.2. 備份多個資料庫

mysqldump -u <username> -p --databases <database1> <database2> ... > backup.sql複製程式碼

2.5.3. 備份所有資料庫

mysqldump -u <username> -p --all-databases > backup.sql複製程式碼

2.5.4. 恢復一個資料庫

Mysql 恢復資料使用 mysqldump 命令。

語法:

mysql -u <username> -p <database> < backup.sql複製程式碼

2.5.5. 恢復所有資料庫

mysql -u <username> -p --all-databases < backup.sql複製程式碼

2.6. 解除安裝

(1)檢視已安裝的 mysql

$ rpm -qa | grep -i mysql
perl-DBD-MySQL-4.023-6.el7.x86_64
mysql80-community-release-el7-1.noarch
mysql-community-common-8.0.12-1.el7.x86_64
mysql-community-client-8.0.12-1.el7.x86_64
mysql-community-libs-compat-8.0.12-1.el7.x86_64
mysql-community-libs-8.0.12-1.el7.x86_64複製程式碼

(2)解除安裝 mysql

$ yum remove mysql-community-server.x86_64複製程式碼

2.7. 主從節點部署

假設需要配置一個主從 Mysql 伺服器環境

  • master 節點:192.168.8.10
  • slave 節點:192.168.8.11

2.7.1. 主節點上的操作

(1)修改配置並重啟

執行 vi /etc/my.cnf ,新增如下配置:

[mysqld]
server-id=1
log_bin=/var/lib/mysql/binlog複製程式碼

  • server-id - 伺服器 ID 號。在主從架構中,每臺機器的 ID 必須唯一。
  • log_bin - 同步的日誌路徑及檔名,一定注意這個目錄要是 mysql 有許可權寫入的;

修改後,重啟 mysql 使配置生效:

$ systemctl restart mysql複製程式碼

(2)建立用於同步的使用者

進入 mysql 命令控制檯:

$ mysql -u root -p
Password:複製程式碼

執行以下 SQL:

-- 建立 slave1 使用者,並指定該使用者只能在主機 192.168.8.11 上登入
mysql> CREATE USER 'slave1'@'192.168.8.11' IDENTIFIED WITH mysql_native_password BY '密碼';
-- 為 slave1 賦予 REPLICATION SLAVE 許可權
mysql> GRANT REPLICATION SLAVE ON *.* TO 'slave1'@'192.168.8.11';
-- 重新整理授權表資訊
mysql> FLUSH PRIVILEGES;複製程式碼

(3)加讀鎖

為了主庫與從庫的資料保持一致,我們先為 mysql 加入讀鎖,使其變為只讀。

mysql> FLUSH TABLES WITH READ LOCK;複製程式碼

(4)檢視主節點狀態

mysql> show master status;
+------------------+----------+--------------+---------------------------------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB                            | Executed_Gtid_Set |
+------------------+----------+--------------+---------------------------------------------+-------------------+
| mysql-bin.000001 |     4202 |              | mysql,information_schema,performance_schema |                   |
+------------------+----------+--------------+---------------------------------------------+-------------------+
1 row in set (0.00 sec)複製程式碼

注意:需要記錄下 FilePosition,後面會用到。

(5)匯出 sql

$ mysqldump -u root -p --all-databases --master-data > dbdump.sql複製程式碼

(6)解除讀鎖

mysql> UNLOCK TABLES;複製程式碼

(7)將 sql 遠端傳送到從節點上

$ scp dbdump.sql [email protected]:/home複製程式碼

2.7.2. 從節點上的操作

(1)修改配置並重啟

執行 vi /etc/my.cnf ,新增如下配置:

[mysqld]
server-id=2
log_bin=/var/lib/mysql/binlog複製程式碼

  • server-id - 伺服器 ID 號。在主從架構中,每臺機器的 ID 必須唯一。
  • log_bin - 同步的日誌路徑及檔名,一定注意這個目錄要是 mysql 有許可權寫入的;

修改後,重啟 mysql 使配置生效:

$ systemctl restart mysql複製程式碼

(2)匯入 sql

$ mysql -u root -p < /home/dbdump.sql複製程式碼

(3)在從節點上建立與主節點的連線

進入 mysql 命令控制檯:

$ mysql -u root -p
Password:複製程式碼

執行以下 SQL:

-- 停止從節點服務
mysql> STOP SLAVE;

mysql> CHANGE MASTER TO
    -> MASTER_HOST='192.168.8.10',-> MASTER_USER='slave1',-> MASTER_PASSWORD='密碼6',-> MASTER_LOG_FILE='binlog.000001',-> MASTER_LOG_POS=4202;複製程式碼

MASTER_LOG_FILEMASTER_LOG_POS 引數要分別與 show master status 指令獲得的 FilePosition 屬性值對應。

(4)啟動 slave 程式

mysql> start slave;複製程式碼

(5)檢視主從同步狀態

mysql> show slave status\G;複製程式碼

說明:如果以下兩項引數均為 YES,說明配置正確。

  • Slave_IO_Running
  • Slave_SQL_Running

(6)將從節點設為只讀

mysql> set global read_only=1;
mysql> set global super_read_only=1;
mysql> show global variables like "%read_only%";
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_read_only      | OFF   |
| read_only             | ON    |
| super_read_only       | ON    |
| transaction_read_only | OFF   |
+-----------------------+-------+複製程式碼

注:設定 slave 伺服器為只讀,並不影響主從同步。

3. 配置

大部分情況下,預設的基本配置已經足夠應付大多數場景,不要輕易修改 Mysql 伺服器配置,除非你明確知道修改項是有益的。

3.1. 配置檔案路徑

配置 Mysql 首先要確定配置檔案在哪兒。

不同 Linux 作業系統上,Mysql 配置檔案路徑可能不同。通常的路徑為 /etc/my.cnf 或 /etc/mysql/my.cnf 。

如果不知道配置檔案路徑,可以嘗試以下操作:

# which mysqld
/usr/sbin/mysqld
# /usr/sbin/mysqld --verbose --help | grep -A 1 'Default options'
Default options are read from the following files in the given order:
/etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf複製程式碼

3.2. 配置項語法

Mysql 配置項設定都使用小寫,單詞之間用下劃線或橫線隔開(二者是等價的)。

建議使用固定的風格,這樣檢索配置項時較為方便。

# 這兩種格式等價
/usr/sbin/mysqld --auto-increment-offset=5
/usr/sbin/mysqld --auto_increment_offset=5複製程式碼

3.3. 常用配置項說明

這裡介紹比較常用的基本配置,更多配置項說明可以參考:Mysql 伺服器配置說明

先給出一份常用配置模板,內容如下:

[mysqld]
# GENERAL
# -------------------------------------------------------------------------------
datadir = /var/lib/mysql
socket  = /var/lib/mysql/mysql.sock
pid_file = /var/lib/mysql/mysql.pid
user = mysql
port = 3306
default_storage_engine = InnoDB
default_time_zone = '+8:00'
character_set_server = utf8mb4
collation_server = utf8mb4_0900_ai_ci

# LOG
# -------------------------------------------------------------------------------
log_error = /var/log/mysql/mysql-error.log
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log

# InnoDB
# -------------------------------------------------------------------------------
innodb_buffer_pool_size = <value>
innodb_log_file_size = <value>
innodb_file_per_table = 1
innodb_flush_method = O_DIRECT

# MyIsam
# -------------------------------------------------------------------------------
key_buffer_size = <value>

# OTHER
# -------------------------------------------------------------------------------
tmp_table_size = 32M
max_heap_table_size = 32M
query_cache_type = 0
query_cache_size = 0
max_connections = <value>
thread_cache = <value>
open_files_limit = 65535

[client]
socket  = /var/lib/mysql/mysql.sock
port = 3306複製程式碼

  • GENERAL
    • datadir - mysql 資料檔案所在目錄
    • socket - scoket 檔案
    • pid_file - PID 檔案
    • user - 啟動 mysql 服務程式的使用者
    • port - 服務埠號,預設 3306
    • default_storage_engine - mysql 5.1 之後,預設引擎是 InnoDB
    • default_time_zone - 預設時區。中國大部分地區在東八區,即 +8:00
    • character_set_server - 資料庫預設字符集
    • collation_server - 資料庫字符集對應一些排序等規則,注意要和 charactersetserver 對應
  • LOG
    • log_error - 錯誤日誌檔案地址
    • slow_query_log - 錯誤日誌檔案地址
  • InnoDB
    • innodb_buffer_pool_size - InnoDB 使用一個緩衝池來儲存索引和原始資料,不像 MyISAM。這裡你設定越大,你在存取表裡面資料時所需要的磁碟 I/O 越少。
      • 在一個獨立使用的資料庫伺服器上,你可以設定這個變數到伺服器實體記憶體大小的 60%-80%
      • 注意別設定的過大,會導致 system 的 swap 空間被佔用,導致作業系統變慢,從而減低 sql 查詢的效率
      • 預設值:128M,建議值:實體記憶體的 60%-80%
    • innodb_log_file_size - 日誌檔案的大小。預設值:48M,建議值:根據你係統的磁碟空間和日誌增長情況調整大小
    • innodb_file_per_table - 說明:mysql5.7 之後預設開啟,意思是,每張表一個獨立表空間。預設值 1,開啟。
    • innodb_flush_method - 說明:控制著 innodb 資料檔案及 redo log 的開啟、刷寫模式,三種模式:fdatasync(預設),ODSYNC,ODIRECT。預設值為空,建議值:使用 SAN 或者 raid,建議用 ODIRECT,不懂測試的話,預設生產上使用 ODIRECT
      • fdatasync:資料檔案,buffer pool->os buffer->磁碟;日誌檔案,buffer pool->os buffer->磁碟;
      • O_DSYNC: 資料檔案,buffer pool->os buffer->磁碟;日誌檔案,buffer pool->磁碟;
      • O_DIRECT: 資料檔案,buffer pool->磁碟; 日誌檔案,buffer pool->os buffer->磁碟;
  • MyIsam
    • key_buffer_size - 指定索引緩衝區的大小,為 MYISAM 資料表開啟供執行緒共享的索引快取,對 INNODB 引擎無效。相當影響 MyISAM 的效能。
      • 不要將其設定大於你可用記憶體的 30%,因為一部分記憶體同樣被 OS 用來緩衝行資料
      • 甚至在你並不使用 MyISAM 表的情況下,你也需要仍舊設定起 8-64M 記憶體由於它同樣會被內部臨時磁碟表使用。
      • 預設值 8M,建議值:對於記憶體在 4GB 左右的伺服器該引數可設定為 256M 或 384M。
      • 注意:該引數值設定的過大反而會是伺服器整體效率降低!
  • OTHER
    • tmp_table_size - 記憶體臨時表的最大值,預設 16M,此處設定成 128M
    • max_heap_table_size - 使用者建立的記憶體表的大小,預設 16M,往往和 tmp_table_size 一起設定,限制使用者臨時表大小。超限的話,MySQL 就會自動地把它轉化為基於磁碟的 MyISAM 表,儲存在指定的 tmpdir 目錄下,增大 IO 壓力,建議記憶體大,增大該數值。
    • query_cache_type - 這個系統變數控制著查詢快取功能的開啟和關閉,0 表示關閉,1 表示開啟,2 表示只要 select 中明確指定 SQL_CACHE 才快取。
    • query_cache_size - 預設值 1M,優點是查詢快取可以極大的提高伺服器速度,如果你有大量的相同的查詢並且很少修改表。缺點:在你表經常變化的情況下或者如果你的查詢原文每次都不同,查詢快取也許引起效能下降而不是效能提升。
    • max_connections - 最大連線數,可設最大值 16384,一般考慮根據同時線上人數設定一個比較綜合的數字,鑑於該數值增大並不太消耗系統資源,建議直接設 10000。如果在訪問時經常出現 Too Many Connections 的錯誤提示,則需要增大該引數值
    • thread_cache - 當客戶端斷開之後,伺服器處理此客戶的執行緒將會快取起來以響應下一個客戶而不是銷燬。可重用,減小了系統開銷。預設值為 9,建議值:兩種取值方式,
      • 方式一,根據實體記憶體,1G —> 8;2G —> 16; 3G —> 32; >3G —> 64;
      • 方式二,根據 show status like 'threads%',檢視 Threads_connected 值。
    • open_files_limit - MySQL 開啟的檔案描述符限制,預設最小 1024;
      • 當 openfileslimit 沒有被配置的時候,比較 max_connections*5 和 ulimit -n 的值,哪個大用哪個,
      • 當 openfilelimit 被配置的時候,比較 openfileslimit 和 max_connections*5 的值,哪個大用哪個
      • 注意:仍然可能出現報錯資訊 Can't create a new thread;此時觀察系統 cat /proc/mysql 程式號/limits,觀察程式 ulimit 限制情況
      • 過小的話,考慮修改系統配置表,/etc/security/limits.conf/etc/security/limits.d/90-nproc.conf

4. 常見問題

4.1. Too many connections

現象

嘗試連線 Mysql 時,遇到 Too many connections 錯誤。

原因

資料庫連線執行緒數超過最大值,訪問被拒絕。

解決方案

如果實際連線執行緒數過大,可以考慮增加伺服器節點來分流;如果實際執行緒數並不算過大,那麼可以配置 max_connections 來增加允許的最大連線數。

(1)檢視最大連線數

mysql> show variables like '%max_connections%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| max_connections        | 151   |
| mysqlx_max_connections | 100   |
+------------------------+-------+複製程式碼

(2)檢視伺服器響應的最大連線數

mysql> show global status like 'Max_used_connections';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| Max_used_connections | 142   |
+----------------------+-------+
1 row in set (0.00 sec)複製程式碼

(3)臨時設定最大連線數

set GLOBAL max_connections=256;複製程式碼

注意:當伺服器重啟時,最大連線數會被重置。

(4)永久設定最大連線數

修改 /etc/my.cnf 配置檔案,在 [mysqld] 新增以下配置:

max_connections=256複製程式碼

重啟 mysql 以生效

(5)修改 Linux 最大檔案數限制

設定了最大連線數,如果還是沒有生效,考慮檢查一下 Linux 最大檔案數

Mysql 最大連線數會受到最大檔案數限制,vim /etc/security/limits.conf,新增 mysql 使用者配置

mysql hard nofile 65535
mysql soft nofile 65535複製程式碼

(6)檢查 LimitNOFILE

如果是使用 rpm 方式安裝 mysql,檢查 mysqld.service 檔案中的 LimitNOFILE 是否配置的太小。

4.2. 時區(time_zone)偏差

現象

資料庫中儲存的 Timestamp 欄位值比真實值少了 13 個小時。

原因

  • 當 JDBC 與 MySQL 開始建立連線時,會獲取伺服器引數。
  • 當 MySQL 的 time_zone 值為 SYSTEM 時,會取 system_time_zone 值作為協調時區,若得到的是 CST 那麼 Java 會誤以為這是 CST -0500 ,因此會給出錯誤的時區資訊(國內一般是CST +0800,即東八區)。

檢視時區方法:

通過 show variables like '%time_zone%'; 命令檢視 Mysql 時區配置:

mysql> show variables like '%time_zone%';
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| system_time_zone | CST    |
| time_zone        | SYSTEM |
+------------------+--------+複製程式碼

解決方案

方案一

mysql> set global time_zone = '+08:00';
Query OK,0 rows affected (0.00 sec)

mysql> set time_zone = '+08:00';
Query OK,0 rows affected (0.00 sec)複製程式碼

方案二

修改 my.cnf 檔案,在 [mysqld] 節下增加 default-time-zone='+08:00' ,然後重啟。

5. 指令碼

這裡推薦我寫的幾個一鍵運維指令碼:

6. 參考資料

7. 傳送門

| 我的 Github 部落格 | db-tutorial 首頁 |

本文由部落格一文多發平臺 OpenWrite 釋出!