MySQL 8 正式版 8.0.11 已釋出,官方表示 MySQL 8 要比 MySQL 5.7 快 2 倍,還帶來了大量的改進和更快的效能!
一. Mysql8.0版本相比之前版本的一些特性
1) 預設編碼utf8
預設編碼使用utf8mb4, utf8mb4編碼是utf8編碼的超集,相容utf8,並且能儲存4位元組的表情字元歷史,MySQL資料庫的 "utf8"並不是真正概念裡的 UTF-8。MySQL中的"utf8"編碼只支援最大3位元組每字元。真正的大家正在使用的UTF-8編碼是應該能支援4位元組每個字元。MySQL的開發者沒有修復這個bug。他們在2010年增加了一個變通的方法:一個新的字符集"utf8mb4"另外,utf-32編碼固定使用4位元組,32bit儲存相比utf8浪費空間。
2) 降序索引
在之前的版本中可以建立,但是實際建立的還是升序索引
mysql> create table t1(id1 int,id2 int,key(id1,id2 desc)); Query OK, 0 rows affected (0.10 sec) mysql> show create table t1 \G; *************************** 1. row *************************** Table: t1 Create Table: CREATE TABLE `t1` ( `id1` int(11) DEFAULT NULL, `id2` int(11) DEFAULT NULL, KEY `id1` (`id1`,`id2` DESC) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci 1 row in set (0.00 sec) ERROR: No query specified
另外,由於降序索引的引入,MySQL 8.0再也不會對group by操作進行隱式排序
3) 隱藏索引
隱藏索引的特性對於效能除錯非常有用。當一個索引隱藏時,它不會被查詢優化器所使用。也就是說,我們可以隱藏一個索引,然後觀察對資料庫的影響。如果資料庫效能有所下降,就說明這個索引是有用的,於是將其“恢復顯示”即可;如果資料庫效能看不出變化,說明這個索引是多餘的,可以刪掉了.
mysql> create index idx2 on t1(id1); Query OK, 0 rows affected (0.35 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> alter table t1 alter index idx2 invisible; Query OK, 0 rows affected (0.09 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> show index from t1 where key_name='idx2' \G; *************************** 1. row *************************** Table: t1 Non_unique: 1 Key_name: idx2 Seq_in_index: 1 Column_name: id1 Collation: A Cardinality: 0 Sub_part: NULL Packed: NULL Null: YES Index_type: BTREE Comment: Index_comment: Visible: NO 1 row in set (0.01 sec) ERROR: No query specified
當索引被隱藏時,它的內容仍然是和正常索引一樣實時更新的,此特性是專門為優化除錯使用。如果長期隱藏一個索引,那還不如干脆刪掉,因為畢竟索引存在會影響插入、更新和刪除的效能.
4) 設定持久化
在oracle中可以使用scope設定引數確定是否到spfile, 現在mysql8.0也可以放在檔案中了,使用方法:
mysql> show variables like 'max_connects'; Empty set (0.07 sec) mysql> show variables like 'max_connections'; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | max_connections | 500 | +-----------------+-------+ 1 row in set (0.01 sec) mysql> set persist max_connections=1000; Query OK, 0 rows affected (0.00 sec) mysql> show variables like 'max_connections'; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | max_connections | 1000 | +-----------------+-------+ 1 row in set (0.01 sec)
可以檢視在資料目錄datadir中的一個mysqld-auto.cnf檔案中儲存了設定,下次啟動時候將用此配置覆蓋預設配置引數
{ "Version" : 1 , "mysql_server" : { "max_connections" : { "Value" : "1000" , "Metadata" : { "Timestamp" : 1540437420567571 , "User" : "root" , "Host" : "" } } } }
5) 通用表表示式(Common Table Expressions)
也可以稱為虛擬檢視,大大簡化複雜查詢
mysql> WITH -> t1 AS (SELECT * FROM t1), -> t2 AS (SELECT * FROM t1) -> SELECT t1.*, t2.* -> FROM t1, t2; +------+------+------+------+ | id1 | id2 | id1 | id2 | +------+------+------+------+ | 1 | 2 | 1 | 2 | +------+------+------+------+ 1 row in set (0.00 sec)
6) 視窗函式(Window Functions)
MySQL 被吐槽最多的特性之一就是缺少 rank() 函式,當需要在查詢當中實現排名時,必須手寫 @ 變數。但是從 8.0 開始,MySQL 新增了一個叫視窗函式的概念,它可以用來實現若干新的查詢方式
說明,視窗可以單獨建立。
mysql> create table tbl2(name varchar(10),amount int); Query OK, 0 rows affected (0.16 sec) mysql> insert into tbl2 values('usa',100),('china',101),('japan',103),('russian',99); Query OK, 4 rows affected (0.13 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> select t1.*,rank() over w as 'rank' from tbl2 as t1 window w as (order by amount); +---------+--------+------+ | name | amount | rank | +---------+--------+------+ | russian | 99 | 1 | | usa | 100 | 2 | | china | 101 | 3 | | japan | 103 | 4 | +---------+--------+------+ 4 rows in set (0.00 sec) mysql> select t1.*,rank() over() as 'rank' from tbl2 as t1; +---------+--------+------+ | name | amount | rank | +---------+--------+------+ | usa | 100 | 1 | | china | 101 | 1 | | japan | 103 | 1 | | russian | 99 | 1 | +---------+--------+------+ 4 rows in set (0.00 sec) mysql> select t1.*,rank() over(order by amount) as 'rank' from tbl2 as t1; +---------+--------+------+ | name | amount | rank | +---------+--------+------+ | russian | 99 | 1 | | usa | 100 | 2 | | china | 101 | 3 | | japan | 103 | 4 | +---------+--------+------+ 4 rows in set (0.00 sec) mysql> select t1.*,sum() over() as 'rank' from tbl2 as t1; ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') over() as 'rank' from tbl2 as t1' at line 1 mysql> select t1.*,sum(amount) over() as 'sum' from tbl2 as t1; +---------+--------+------+ | name | amount | sum | +---------+--------+------+ | usa | 100 | 403 | | china | 101 | 403 | | japan | 103 | 403 | | russian | 99 | 403 | +---------+--------+------+ 4 rows in set (0.00 sec)
7) 安全性
對 OpenSSL 的改進、新的預設身份驗證、SQL 角色、密碼強度、授權。MySQL現在維護關於密碼歷史的資訊,允許對以前密碼的重用進行限制
比如常見的一個連線錯誤,參考:https://blog.csdn.net/jc_benben/article/details/80652897
8) 增加JSON (json enhancements)AND OpenGIS spatial types
mysql提供了很多json相關的函式和API介面,新增了基於路徑查詢引數從 JSON 欄位中抽取資料的 JSON_EXTRACT() 函式,以及用於將資料分別組合到 JSON 陣列和物件中的 JSON_ARRAYAGG() 和 JSON_OBJECTAGG() 聚合函式
9) 原子資料定義語句(原子DDL)(Atomic Data Definition Statements (Atomic DDL))
10) 資源管理(Resource management)
MySQL現在支援資源組的建立和管理,並允許將伺服器內執行的執行緒分配給特定組,以便執行緒根據組可用的資源執行。組屬性可以控制其資源,以啟用或限制組中執行緒的資源消耗
11) Data dictionary
MySQL現在包含一個事務資料字典,用於儲存有關資料庫物件的資訊,In previous MySQL releases, dictionary data was stored in metadata files and nontransactional tables
比如myisam和innodb表定義frm檔案等.
12) innodb的增強
1 每次值更改時,當前最大自動增量計數器值將寫入重做日誌,並儲存到每個檢查點上的引擎專用系統表中。這些更改使當前最大自動增量計數器值在伺服器重新啟動時保持不變。
2 遇到索引樹損壞時, InnoDB將損壞標誌寫入重做日誌,這會使損壞標誌崩潰安全。InnoDB還將記憶體中損壞標誌資料寫入每個檢查點上的引擎專用系統表。在恢復期間, InnoDB從兩個位置讀取損壞標誌並在將記憶體表和索引物件標記為損壞之前合併結果。
3 InnoDB 分散式快取外掛支援多個get操作(讀取在一個單一的多鍵/值對分散式快取查詢)和範圍查詢;
4 新的動態配置選項 innodb_deadlock_detect可用於禁用死鎖檢測。在高併發系統上,當許多執行緒等待同一個鎖時,死鎖檢測會導致速度減慢。有時,禁用死鎖檢測可能更有效,並且在innodb_lock_wait_timeout發生死鎖時依賴於事務回滾的設定。
5 INFORMATION_SCHEMA.INNODB_CACHED_INDEXES 表報告InnoDB每個索引緩衝池中快取的索引頁數 。
6 InnoDB現在,在共享臨時表空間中建立臨時表ibtmp1。
7 InnoDB 表空間加密功能支援重做日誌的加密和撤消日誌資料;
8 InnoDB支援 NOWAIT和SKIP LOCKED選項SELECT ... FOR SHARE以及SELECT ... FOR UPDATE鎖定讀取語句。 NOWAIT如果請求的行被另一個事務鎖定,則會立即返回該語句。SKIP LOCKED從結果集中刪除鎖定的行SELECT ... FOR SHARE替換 SELECT ... LOCK IN SHARE MODE,但LOCK IN SHARE MODE仍可用於向後相容;
9 支援ADD PARTITION,DROP PARTITION,COALESCE PARTITION,REORGANIZE PARTITION,和REBUILD PARTITION ALTER TABLE選項;
10 InnoDB儲存引擎現在使用MySQL的資料字典,而不是它自己的儲存引擎特定的資料字典;
11 mysql系統表和資料字典表現在在MySQL資料目錄中InnoDB命名的單個表空間檔案建立mysql.ibd。以前,這些表是InnoDB在mysql資料庫目錄中的各個表空間檔案中建立的;
二. Mysql8.0安裝 (YUM方式)
1) 首先刪除系統預設或之前可能安裝的其他版本的mysql [root@DB-node01 ~]# for i in $(rpm -qa|grep mysql);do rpm -e $i --nodeps;done [root@DB-node01 ~]# rm -rf /var/lib/mysql && rm -rf /etc/my.cnf 2) 安裝Mysql8.0 的yum資源庫 mysql80-community-release-el7-1.noarch.rpm 下載地址: https://pan.baidu.com/s/1QzYaSnzAQeTqAmk8FE9doA 提取密碼: 2maw [root@DB-node01 ~]# yum localinstall https://repo.mysql.com//mysql80-community-release-el7-1.noarch.rpm 3) 安裝Mysql8.0 [root@DB-node01 ~]# yum install mysql-community-server 啟動MySQL伺服器和MySQL的自動啟動 [root@DB-node01 ~]# systemctl start mysqld [root@DB-node01 ~]# systemctl enable mysqld 4) 使用預設密碼初次登入後, 必須要重置密碼 檢視預設密碼, 如下預設密碼為"e53xDalx.*dE" [root@DB-node01 ~]# grep 'temporary password' /var/log/mysqld.log 2019-03-06T01:53:19.897262Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: e53xDalx.*dE [root@DB-node01 ~]# mysql -pe53xDalx.*dE ............ mysql> select version(); ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement. 報錯提示必須要重置初始密碼, 下面開始重置mysql登入密碼(注意要切換到mysql資料庫,使用use mysql) mysql> use mysql; ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement. mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '123456'; ERROR 1819 (HY000): Your password does not satisfy the current policy requirements 這個其實與validate_password_policy的值有關, mysql8.0更改了validate_password_policy相關的配置名稱, 這跟Mysql5.7有點不一樣了. mysql> set global validate_password.policy=0; Query OK, 0 rows affected (0.00 sec) mysql> set global validate_password.length=1; Query OK, 0 rows affected (0.00 sec) 接著再修改密碼 mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '123456'; Query OK, 0 rows affected (0.05 sec) mysql> flush privileges; Query OK, 0 rows affected (0.03 sec) 退出, 重新使用新密碼登入mysql [root@DB-node01 ~]# mysql -p123456 ........... mysql> select version(); +-----------+ | version() | +-----------+ | 8.0.15 | +-----------+ 1 row in set (0.00 sec) 檢視服務埠 mysql> show global variables like 'port'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | port | 3306 | +---------------+-------+ 1 row in set (0.01 sec) 檢視mysql連線的授權資訊 mysql> select host,user,password from mysql.user; ERROR 1054 (42S22): Unknown column 'password' in 'field list' 上面這是mysql5.6及以下版本的檢視命令, mysql5.7之後的資料庫裡mysql.user表裡已經沒有password這個欄位了,password欄位改成了authentication_string。 mysql> select host,user,authentication_string from mysql.user; +-----------+------------------+------------------------------------------------------------------------+ | host | user | authentication_string | +-----------+------------------+------------------------------------------------------------------------+ | localhost | mysql.infoschema | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | mysql.session | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | mysql.sys | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | root | $A$005${7J0=4Dc7Jym8eI/FU4jimKWFvkD9XmoAkF1ca5.Un0bc6zgmPtU.0 | +-----------+------------------+------------------------------------------------------------------------+ 4 rows in set (0.00 sec) =============================mysql8.0修改使用者密碼命令================================ mysql> use mysql; mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '123456'; mysql> flush privileges;
三. Mysql8.0安裝 (二進位制方式)
1) 首先刪除系統預設或之前可能安裝的其他版本的mysql [root@mysql8-node ~]# for i in $(rpm -qa|grep mysql);do rpm -e $i --nodeps;done [root@mysql8-node ~]# rm -rf /var/lib/mysql && rm -rf /etc/my.cnf 2) 安裝需要的軟體包 [root@mysql8-node ~]# yum -y install libaio [root@mysql8-node ~]# yum -y install net-tools 3) 下載並安裝Mysql8.0.12 下載地址: https://pan.baidu.com/s/1LyXrkrCPP7QKLrWYbLRBlw 提取密碼: emmf [root@mysql8-node ~]# groupadd mysql [root@mysql8-node ~]# useradd -g mysql mysql [root@mysql8-node ~]# cd /usr/local/src/ [root@mysql-node src]# ll -rw-r--r-- 1 root root 620389228 Aug 22 2018 mysql8.0.12_bin_centos7.tar.gz [root@mysql-node src]# tar -zvxf mysql8.0.12_bin_centos7.tar.gz [root@mysql-node src]# mv mysql /usr/local/ [root@mysql-node src]# chown -R mysql.mysql /usr/local/mysql [root@mysql-node src]# vim /home/mysql/.bash_profile export PATH=/usr/local/mysql/bin:/usr/local/mysql/lib:$PATH [root@mysql-node src]# source /home/mysql/.bash_profile [root@mysql-node src]# echo "PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile [root@mysql-node src]# source /etc/profile 4) 建立資料目錄 [root@mysql-node src]# mkdir -p /data/mysql/{data,log,binlog,conf,tmp} [root@mysql-node src]# chown -R mysql.mysql /data/mysql 5) 配置mysql [root@mysql-node src]# su - mysql [mysql@mysql-node ~]$ vim /data/mysql/conf/my.cnf [mysqld] lower_case_table_names = 1 user = mysql server_id = 1 port = 3306 default-time-zone = '+08:00' enforce_gtid_consistency = ON gtid_mode = ON binlog_checksum = none default_authentication_plugin = mysql_native_password datadir = /data/mysql/data pid-file = /data/mysql/tmp/mysqld.pid socket = /data/mysql/tmp/mysqld.sock tmpdir = /data/mysql/tmp/ skip-name-resolve = ON open_files_limit = 65535 table_open_cache = 2000 #################innodb######################## innodb_data_home_dir = /data/mysql/data innodb_data_file_path = ibdata1:512M;ibdata2:512M:autoextend innodb_buffer_pool_size = 12000M innodb_flush_log_at_trx_commit = 1 innodb_io_capacity = 600 innodb_lock_wait_timeout = 120 innodb_log_buffer_size = 8M innodb_log_file_size = 200M innodb_log_files_in_group = 3 innodb_max_dirty_pages_pct = 85 innodb_read_io_threads = 8 innodb_write_io_threads = 8 innodb_thread_concurrency = 32 innodb_file_per_table innodb_rollback_on_timeout innodb_undo_directory = /data/mysql/data innodb_log_group_home_dir = /data/mysql/data ###################session########################### join_buffer_size = 8M key_buffer_size = 256M bulk_insert_buffer_size = 8M max_heap_table_size = 96M tmp_table_size = 96M read_buffer_size = 8M sort_buffer_size = 2M max_allowed_packet = 64M read_rnd_buffer_size = 32M ############log set################### log-error = /data/mysql/log/mysqld.err log-bin = /data/mysql/binlog/binlog log_bin_index = /data/mysql/binlog/binlog.index max_binlog_size = 500M slow_query_log_file = /data/mysql/log/slow.log slow_query_log = 1 long_query_time = 10 log_queries_not_using_indexes = ON log_throttle_queries_not_using_indexes = 10 log_slow_admin_statements = ON log_output = FILE,TABLE master_info_file = /data/mysql/binlog/master.info 6) 初始化 (稍等一會兒, 可以到/data/mysql/log/mysqld.err日子裡檢視初始化過程, 看看有沒有error資訊) [mysql@mysql-node ~]$ mysqld --defaults-file=/data/mysql/conf/my.cnf --initialize-insecure --user=mysql 7) 啟動mysqld [mysql@mysql-node ~]$ mysqld_safe --defaults-file=/data/mysql/conf/my.cnf & [mysql@mysql-node ~]$ lsof -i:3306 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mysqld 24743 mysql 23u IPv6 23132988 0t0 TCP *:mysql (LISTEN) 8) 登入mysql, 重置密碼 本地首次使用sock檔案登入mysql是不需要密碼的 [mysql@mysql-node ~]# mysql -S /data/mysql/tmp/mysqld.sock ............. mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '123456'; Query OK, 0 rows affected (0.07 sec) mysql> flush privileges; Query OK, 0 rows affected (0.03 sec) mysql> select host,user,authentication_string from mysql.user; +-----------+------------------+------------------------------------------------------------------------+ | host | user | authentication_string | +-----------+------------------+------------------------------------------------------------------------+ | localhost | mysql.infoschema | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | mysql.session | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | mysql.sys | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | root | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | +-----------+------------------+------------------------------------------------------------------------+ 4 rows in set (0.00 sec) 退出, 此時密碼重置後, 就不能使用sock檔案無密碼登入了 [root@mysql-node ~]# mysql -S /data/mysql/tmp/mysqld.sock ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO) [root@mysql-node ~]# mysql -p123456 mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) 做sock檔案的軟連結 [root@mysql-node ~]# ln -s /data/mysql/tmp/mysqld.sock /tmp/mysql.sock [root@mysql-node ~]# mysql -p123456 或者 [root@mysql-node ~]# mysql -uroot -S /data/mysql/tmp/mysqld.sock -p123456 ............. mysql> select version(); +-----------+ | version() | +-----------+ | 8.0.12 | +-----------+ 1 row in set (0.00 sec) #授予使用者許可權. 必須先要建立使用者, 才能授權!! (建立使用者時要帶@並指定地址, 則grant授權時的地址就是這個@後面指定的!, 否則grant授權就會報錯!) mysql> create user 'kevin'@'%' identified by '123456'; Query OK, 0 rows affected (0.11 sec) mysql> grant all privileges on *.* to 'kevin'@'%' with grant option; Query OK, 0 rows affected (0.21 sec) mysql> select host,user,authentication_string from mysql.user; +-----------+------------------+------------------------------------------------------------------------+ | host | user | authentication_string | +-----------+------------------+------------------------------------------------------------------------+ | % | kevin | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | | localhost | mysql.infoschema | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | mysql.session | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | mysql.sys | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | root | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | +-----------+------------------+------------------------------------------------------------------------+ 5 rows in set (0.00 sec) mysql> update mysql.user set host='172.16.60.%' where user="kevin"; Query OK, 1 row affected (0.16 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> flush privileges; Query OK, 0 rows affected (0.05 sec) mysql> select host,user,authentication_string from mysql.user; +-------------+------------------+------------------------------------------------------------------------+ | host | user | authentication_string | +-------------+------------------+------------------------------------------------------------------------+ | 172.16.60.% | kevin | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | | localhost | mysql.infoschema | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | mysql.session | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | mysql.sys | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | root | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | +-------------+------------------+------------------------------------------------------------------------+ 5 rows in set (0.00 sec) mysql> create user 'bobo'@'172.16.60.%' identified by '123456'; Query OK, 0 rows affected (0.09 sec) mysql> grant all privileges on *.* to 'bobo'@'172.16.60.%'; Query OK, 0 rows affected (0.17 sec) mysql> flush privileges; Query OK, 0 rows affected (0.04 sec) mysql> select host,user,authentication_string from mysql.user; +-------------+------------------+------------------------------------------------------------------------+ | host | user | authentication_string | +-------------+------------------+------------------------------------------------------------------------+ | 172.16.60.% | bobo | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | | 172.16.60.% | kevin | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | | localhost | mysql.infoschema | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | mysql.session | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | mysql.sys | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | root | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | +-------------+------------------+------------------------------------------------------------------------+ 6 rows in set (0.00 sec) mysql> show grants for kevin@'172.16.60.%'; +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Grants for kevin@172.16.60.% | +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, CREATE ROLE, DROP ROLE ON *.* TO `kevin`@`172.16.60.%` WITH GRANT OPTION | +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
MySQL單機多例項安裝配置
通過上面二進位制部署可知, 已經起來一個3306埠的MySQL例項, 現在需要再起來兩個例項, 分別為3307, 3308. 操作如下:
建立例項的資料目錄 [root@mysql-node ~]# mkdir -p /data/mysql3307/{data,log,binlog,conf,tmp} [root@mysql-node ~]# mkdir -p /data/mysql3308/{data,log,binlog,conf,tmp} [root@mysql-node ~]# chown -R mysql.mysql /data/mysql3307 [root@mysql-node ~]# chown -R mysql.mysql /data/mysql3308 配置mysql [root@mysql-node ~]# cp -r /data/mysql/conf/my.cnf /data/mysql3307/conf/ [root@mysql-node ~]# cp -r /data/mysql/conf/my.cnf /data/mysql3308/conf/ [root@mysql-node ~]# sed -i 's#/data/mysql/#/data/mysql3307/#g' /data/mysql3307/conf/my.cnf [root@mysql-node ~]# sed -i 's#/data/mysql/#/data/mysql3308/#g' /data/mysql3308/conf/my.cnf [root@mysql-node ~]# sed -i 's/3306/3307/g' /data/mysql3307/conf/my.cnf [root@mysql-node ~]# sed -i 's/3306/3308/g' /data/mysql3308/conf/my.cnf [root@mysql-node ~]# chown -R mysql.mysql /data/mysql* 進行初始化兩個例項 [root@mysql-node ~]# mysqld --defaults-file=/data/mysql3307/conf/my.cnf --initialize-insecure --user=mysql [root@mysql-node ~]# mysqld --defaults-file=/data/mysql3308/conf/my.cnf --initialize-insecure --user=mysql 接著啟動mysqld [root@mysql-node ~]# mysqld_safe --defaults-file=/data/mysql3307/conf/my.cnf & [root@mysql-node ~]# mysqld_safe --defaults-file=/data/mysql3308/conf/my.cnf & [root@mysql-node ~]# ps -ef|grep mysql mysql 23996 1 0 14:37 ? 00:00:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --defaults-file=/data/mysql/conf/my.cnf mysql 24743 23996 0 14:38 ? 00:00:17 /usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/conf/my.cnf --basedir=/usr/local/mysql --datadir=/data/mysql/data --plugin-dir=/usr/local/mysql/lib/plugin --log-error=/data/mysql/log/mysqld.err --open-files-limit=65535 --pid-file=/data/mysql/tmp/mysqld.pid --socket=/data/mysql/tmp/mysqld.sock --port=3306 root 30473 23727 0 15:33 pts/0 00:00:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --defaults-file=/data/mysql3307/conf/my.cnf mysql 31191 30473 17 15:33 pts/0 00:00:02 /usr/local/mysql/bin/mysqld --defaults-file=/data/mysql3307/conf/my.cnf --basedir=/usr/local/mysql --datadir=/data/mysql3307/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/data/mysql3307/log/mysqld.err --open-files-limit=65535 --pid-file=/data/mysql3307/tmp/mysqld.pid --socket=/data/mysql3307/tmp/mysqld.sock --port=3307 root 31254 23727 0 15:33 pts/0 00:00:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --defaults-file=/data/mysql3308/conf/my.cnf mysql 31977 31254 39 15:33 pts/0 00:00:02 /usr/local/mysql/bin/mysqld --defaults-file=/data/mysql3308/conf/my.cnf --basedir=/usr/local/mysql --datadir=/data/mysql3308/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/data/mysql3308/log/mysqld.err --open-files-limit=65535 --pid-file=/data/mysql3308/tmp/mysqld.pid --socket=/data/mysql3308/tmp/mysqld.sock --port=3308 root 32044 23727 0 15:34 pts/0 00:00:00 grep --color=auto mysql [root@mysql-node ~]# lsof -i:3307 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mysqld 31191 mysql 22u IPv6 23144844 0t0 TCP *:opsession-prxy (LISTEN) [root@mysql-node ~]# lsof -i:3308 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mysqld 31977 mysql 22u IPv6 23145727 0t0 TCP *:tns-server (LISTEN) [root@mysql-node ~]# lsof -i:3306 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mysqld 24743 mysql 23u IPv6 23132988 0t0 TCP *:mysql (LISTEN) 登入3307埠例項, 並設定密碼 [root@mysql-node ~]# mysql -S /data/mysql3307/tmp/mysqld.sock ............ mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '123456'; Query OK, 0 rows affected (0.11 sec) mysql> flush privileges; Query OK, 0 rows affected (0.11 sec) 退出, 使用新密碼登入 [root@mysql-node ~]# mysql -uroot -S /data/mysql3307/tmp/mysqld.sock -p123456 ............. mysql> 同理, 登入3308埠例項, 並設定密碼 [root@mysql-node ~]# mysql -S /data/mysql3308/tmp/mysqld.sock ........... mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '123456'; Query OK, 0 rows affected (0.13 sec) mysql> flush privileges; Query OK, 0 rows affected (0.03 sec) 退出, 使用新密碼登入 [root@mysql-node ~]# mysql -uroot -S /data/mysql3308/tmp/mysqld.sock -p123456 .................... mysql> ========================================== 3306, 3307, 3308三個埠例項的啟動命令分別為: mysqld_safe --defaults-file=/data/mysql/conf/my.cnf & mysqld_safe --defaults-file=/data/mysql3307/conf/my.cnf & mysqld_safe --defaults-file=/data/mysql3308/conf/my.cnf & 登入命令分別為: mysql -uroot -S /data/mysql/tmp/mysqld.sock -p123456 mysql -uroot -S /data/mysql3307/tmp/mysqld.sock -p123456 mysql -uroot -S /data/mysql3308/tmp/mysqld.sock -p123456
編寫mysql多埠例項的登入指令碼
上面的多埠例項配置之後, 檢視一個登入指令碼:myin (注意將指令碼中的密碼改為自己的密碼) [root@mysql-node ~]# ll /usr/local/mysql/bin/myin -rwxrwxr-x 1 mysql mysql 161 Aug 22 2018 /usr/local/mysql/bin/myin [root@mysql-node ~]# cat /usr/local/mysql/bin/myin #!/bin/bash p=$1 shift mysql -h"127.0.0.1" -P"$p" --default-character-set=utf8mb4 --show-warnings -uroot -p'123456' -A --prompt="(\u@\p)[\d]> " "$@" 嘗試登入 [mysql@mysql-node ~]# myin 3306 mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1130 (HY000): Host '127.0.0.1' is not allowed to connect to this MySQL server 這是因為各個埠例項中的root使用者授權的是localhost, 而不是127.0.0.1, 則可以再次新增一個針對127.0.0.1的root使用者授權 或者將myin指令碼中的127.0.0.1 修改為 localhost [root@mysql-node ~]# sed -i 's/127.0.0.1/localhost/g' /usr/local/mysql/bin/myin [root@mysql-node ~]# cat /usr/local/mysql/bin/myin #!/bin/bash p=$1 shift mysql -h"localhost" -P"$p" --default-character-set=utf8mb4 --show-warnings -uroot -p'123456' -A --prompt="(\u@\p)[\d]> " "$@" 則現在可以登入各個例項了, 登入命令為"myin port" 登入3306埠例項 [root@mysql-node ~]# myin 3306 mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 27 Server version: 8.0.12 MySQL Community Server - GPL Copyright (c) 2000, 2018, 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. (root@mysql.sock)[(none)]> 登入3307埠例項 [root@mysql-node ~]# myin 3307 mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 28 Server version: 8.0.12 MySQL Community Server - GPL Copyright (c) 2000, 2018, 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. (root@mysql.sock)[(none)]> 登入3308埠例項 [root@mysql-node ~]# myin 3308 mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 29 Server version: 8.0.12 MySQL Community Server - GPL Copyright (c) 2000, 2018, 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. (root@mysql.sock)[(none)]>
生產環境下的思路: 同一個業務庫單獨放在一個例項下, 不要混用資料庫. 單機多例項間可以做主從或主主同步, 也可以在多機多例項之間坐主從或主主同步.
比如:
A機器有三個例項: 3310, 3311, 3312
B機器有三個例項: 3310, 3311, 3312
C機器有三個例項: 3310, 3311, 3312
則三臺機器的每個對應的埠例項之間做主從或主主同步(GTID, MGR), 一主兩從, 或三主模式. (多例項環境最好不要用3306埠, 否則經常會出現一些誤操作)
四. Mysql8.0使用過程中踩過的一些坑
1) 建立使用者和授權
在mysql8.0建立使用者和授權和之前不太一樣了,其實嚴格上來講,也不能說是不一樣, 只能說是更嚴格, mysql8.0需要先建立使用者(建立使用者時要帶@並指定地址, 則grant授權時的地址就是這個@後面指定的!, 否則grant授權就會報錯!)和設定密碼,然後才能授權。
mysql> create user 'kevin'@'%' identified by '123456'; Query OK, 0 rows affected (0.04 sec) mysql> grant all privileges on *.* to 'kevin'@'%' with grant option; Query OK, 0 rows affected (0.04 sec) mysql> create user 'bobo'@'%' identified by '123456'; Query OK, 0 rows affected (0.06 sec) mysql> grant all privileges on *.* to 'bobo'@'%' with grant option; Query OK, 0 rows affected (0.03 sec) mysql> flush privileges; Query OK, 0 rows affected (0.04 sec) mysql> select host,user,authentication_string from mysql.user; +-----------+------------------+------------------------------------------------------------------------+ | host | user | authentication_string | +-----------+------------------+------------------------------------------------------------------------+ | % | bobo | $A$005$1VY")q?G6<^X@-6LsXrPt5C0TwlTuvHbaOa3sYF0DKViIGoRPuCF8AzwiFcim1 | | % | kevin | $A$005$hy`U}ZB#R::rA8W0y2rmwgySqzv0rmR1eTeNDSaXfQPWIsrh7ytbVdi85 | | localhost | mysql.infoschema | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | mysql.session | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | mysql.sys | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | root | $A$005$/VO_y^7,]6;2qxggBLmJzhA0Qylu5/AHuRScZ/ykKedgZKh/6krOIzPs2 | +-----------+------------------+------------------------------------------------------------------------+
如果還是用Mysql5.7及之前版本的直接授權的方法, 會有報錯:
mysql> grant all privileges on *.* to 'shibo'@'%' identified by '123456'; ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'identified by '123456'' at line 1
2) Mysql8.0預設是不能使用root賬號進行遠端登入的! root賬號只能本地登入!
mysql> select host,user,authentication_string from mysql.user; +-----------+------------------+------------------------------------------------------------------------+ | host | user | authentication_string | +-----------+------------------+------------------------------------------------------------------------+ | % | bobo | $A$005$1VY")q?G6<^X@-6LsXrPt5C0TwlTuvHbaOa3sYF0DKViIGoRPuCF8AzwiFcim1 | | % | kevin | $A$005$hy`U}ZB#R::rA8W0y2rmwgySqzv0rmR1eTeNDSaXfQPWIsrh7ytbVdi85 | | localhost | mysql.infoschema | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | mysql.session | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | mysql.sys | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | root | $A$005$/VO_y^7,]6;2qxggBLmJzhA0Qylu5/AHuRScZ/ykKedgZKh/6krOIzPs2 | +-----------+------------------+------------------------------------------------------------------------+ 6 rows in set (0.00 sec) 如果想要遠端登入, 則需要進行update更新下root賬號的許可權 mysql> update mysql.user set host='%' where user="root"; Query OK, 1 row affected (0.10 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> flush privileges; Query OK, 0 rows affected (0.14 sec) mysql> select host,user,authentication_string from mysql.user; +-----------+------------------+------------------------------------------------------------------------+ | host | user | authentication_string | +-----------+------------------+------------------------------------------------------------------------+ | % | bobo | $A$005$1VY")q?G6<^X@-6LsXrPt5C0TwlTuvHbaOa3sYF0DKViIGoRPuCF8AzwiFcim1 | | % | kevin | $A$005$hy`U}ZB#R::rA8W0y2rmwgySqzv0rmR1eTeNDSaXfQPWIsrh7ytbVdi85 | | % | root | $A$005$/VO_y^7,]6;2qxggBLmJzhA0Qylu5/AHuRScZ/ykKedgZKh/6krOIzPs2 | | localhost | mysql.infoschema | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | mysql.session | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | mysql.sys | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | +-----------+------------------+------------------------------------------------------------------------+ 6 rows in set (0.00 sec)
這樣就能在遠端使用root賬號登入該mysql8.0的資料庫了
3) 修改root賬號許可權, 允許root賬號遠端登入後, 用navicat進行mysql的遠端連線時,出現了彈窗報錯:
出現這個原因是mysql8 之前的版本中加密規則是mysql_native_password, 而在mysql8之後,加密規則是caching_sha2_password, 解決問題方法有兩種:
1) 一種是升級navicat驅動;
2) 一種是把mysql使用者登入密碼加密規則還原成mysql_native_password;
這裡選擇第二種方法來解決:
#修改加密規則 mysql> ALTER USER 'root'@'%' IDENTIFIED BY '123456' PASSWORD EXPIRE NEVER; Query OK, 0 rows affected (0.16 sec) #更新一下使用者的密碼 mysql> ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456'; Query OK, 0 rows affected (0.08 sec) #重新整理許可權 mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.03 sec)
這樣問題就解決了。
4) sqlyog連結時出現2058異常
1) 使用sqlyog連結時會出現2058的異常,此時我們需要修改mysql,命令列登入mysql(與修改密碼中登入相同,使用修改後的密碼),然後執行下面的命令: mysql > ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'; 其中password為自己修改的密碼。然後SQLyog中重新連線,則可連線成功,OK。 2) 如果報錯:ERROR 1396 (HY000): Operation ALTER USER failed for 'root'@'localhost'則使用下面命令: mysql > ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'password';
5) 修改預設編碼方式
mysql8.0預設編碼方式為utf8mb4,因此使用時不需要修改,可使用如下命令檢視: mysql > SHOW VARIABLES WHERE Variable_name LIKE 'character_set_%' OR Variable_name LIKE 'collation%'; 如果需要修改其他編碼方式,比如需要修改為utf8mb4,可以使用如下方式: 修改mysql配置檔案my.cnf, 找到後請在以下三部分裡新增如下內容: [client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4 [mysqld] character-set-client-handshake = FALSE character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci init_connect='SET NAMES utf8mb4' 然後重啟mysqld服務即可, 其中: character_set_client (客戶端來源資料使用的字符集) character_set_connection (連線層字符集) character_set_database (當前選中資料庫的預設字符集) character_set_results (查詢結果字符集) character_set_server (預設的內部操作字符集) ======================================== 資料庫連線引數中: characterEncoding=utf8 會被自動識別為utf8mb4,也可以不加這個引數,會自動檢測。 而autoReconnect=true 是必須加上的。
6) 部分引數配置查詢命令
#查詢mysql最大連線數設定
mysql> show global variables like 'max_conn%';
mysql> SELECT @@MAX_CONNECTIONS AS 'Max Connections';
# 檢視最大連結數
mysql> show global status like 'Max_used_connections';
# 檢視慢查詢日誌是否開啟以及日誌位置
mysql> show variables like 'slow_query%';
# 檢視慢查詢日誌超時記錄時間
mysql> show variables like 'long_query_time';
# 檢視連結建立以及現在正在連結數
mysql> show status like 'Threads%';
# 檢視資料庫當前連結
mysql> show processlist;
# 檢視資料庫配置
mysql> show variables like '%quer%';