運維這塊逆天只能說夠用,並不能說擅長,因此這篇就當拋磚之用,歡迎補充和糾錯html
PS:再說明下CentOS優化策略
這部分的內容來源:首先這塊逆天不是很擅長,因此主要是參考網上的DBA文章,以後請教了下運維相關的朋友,你們辯證看就好了,我只能保證90%的準確度(具體看業務)mysql
RAID:磁盤冗餘隊列linux
把多個容量小的磁盤組成一組容量更大的磁盤,並提供數據冗餘來保證數據完整性的技術redis
RAID0
:數據條帶(好處:成本低,應用:數據備份)算法
須要硬盤數>=2,數據沒有冗餘或修復功能,只是多個小容量變成大容量的功能sql
RAID1:磁盤鏡像(好處:數據安全、讀很快)shell
磁盤的數據鏡像到另外一個磁盤上,最大限度的保證系統的可靠性和可修復性數據庫
RAID5
:分佈式奇偶校驗磁盤陣列(好處:性價比高,缺點:兩塊磁盤失效則整個卷的數據都沒法恢復,應用:從數據庫)django
把數據分散到多個磁盤上,若是任何一個盤數據失效均可以從奇偶校驗塊中重建centos
RAID10:分片鏡像(優勢:讀寫性能良好,相對RAID5重建更簡單速度更快,缺點:貴)
對磁盤先作RAID1以後對兩組RAID1的磁盤再作RAID0
RAID級別 | 特色 | 備份 | 盤數 | 讀 | 寫 |
---|---|---|---|---|---|
RAID0 |
便宜,讀寫快,不安全 | 沒有 | N | 快 | 快 |
RAID1 |
貴,高速讀,最安全 | 有 | 2N | 快 | 慢 |
RAID5 |
性價比高,讀快,安全 | 有 | N+1 | 快 | 取決於最慢盤 |
RAID10 |
貴,高速,安全 | 有 | 2N | 快 | 快 |
SAN:經過專用高速網將一個或多個網絡存儲設備和服務器鏈接起來的專用存儲系統
經過光纖鏈接到服務器,設備經過塊接口訪問,服務器能夠將其當作硬盤使用
NAS:鏈接在網絡上, 具有資料存儲功能的裝置,以數據爲中心,將存儲設備與服務器完全分離,集中管理數據,從而釋放帶寬、提升性能、下降總擁有成本、保護投資。其成本遠遠低於使用服務器存儲,而效率卻遠遠高於後者
使用網絡進行鏈接,經過基於文件協議(NFS、SMB)來訪問
PS:網絡存儲通常都是用來搭建開發環境或者數據庫備份
QPS
(Queries Per Second):每秒鐘處理的請求數(通常都是查詢,但DML、DDL也包括)
eg:
10ms
處理1個sql,1s處理100個sql,那麼QPS<=100
(100ms
處理1個sql,QPS<=10)
TPS
(Transactions Per Second):每秒鐘系統可以處理的交易或事務的數量(每秒事務數|消息數
)
一個事務是指一個客戶機向服務器發送請求而後服務器作出反應的過程。客戶機在發送請求時開始計時,收到服務器響應後結束計時,以此來計算使用的時間和完成的事務個數
PS:QPS看的多些
1.超高的CPU|內存使用率:容易因CPU|內存資源耗盡而宕機
PS:若是是CPU密集型:須要更好的CPU;須要更大的併發量:須要更多的CPU(WEB項目)
MySQL有同一數據中屢次寫操做合併爲一次寫操做
2.併發量大:容易致使數據庫鏈接數被佔滿
PS:MySQL的
max_connections
默認是100(根據硬件條件調整)
3.磁盤IO:致使性能直線降低(熱點數據內存放不下時
)
解決:按期整理磁盤碎片、
RAID加強傳統硬盤
、SSD
、Fusion-io
(PCIe)、網絡存儲NAS or ASN
PS:SSD應用於存在大量隨機IO
或解決單線程IO瓶頸
的場景
4.網卡流量(網絡):容易出現沒法鏈接數據庫的現象
解決:
- 減小從服務器的數量
- 分級緩存(防止同一時間緩存的大量失效)
- 避免使用
select *
進行查詢(減小傳輸過程當中的無用字節)- 分離業務網絡和服務器網絡
5.大表定義:單表數據量超過千萬行 or 表數據文件超過10G
問題:大表更容易出現慢查詢、DDL也很慢也容易致使其餘問題
解決:分庫分表(拆分爲多個小表)
PS:分庫分表前能夠對大表的歷史數據進行歸檔(冷熱數據隔離)【核心:歸檔時間點的選擇】
DDL影響的補充說明:
建索引很慢
,並且會引發長時間的主從延遲修改表結構須要長時間鎖表
分庫分表容易出現的問題:
雪花算法
來解決PS:不太影響的案例:日誌表(insert
和select
不少,不多delete和update)
6.大事務定義:運行時間較長,操做數據比較多的事物
問題:
- 鎖定太多的數據,形成大量的阻塞和鎖超時
- 回滾須要的時間很長(又得鎖一段時間了)
- 執行時間長,容易致使主從的延遲
解決:- 避免一次處理大量數據(分批處理)
- 去除在事物中沒必要要的select語句(通常都是事物中使用過多查詢致使的)
- PS:select徹底能夠在事物外查詢,事物專一於寫
SQL標準中定義的4種隔離級別:
read uncommited
)read commited
)
repeatable read
)
innodb的默認隔離級別
serializable
)併發性高到低
PS:查看事物隔離級別-show variables like '%iso%';
,設置會話的隔離級別:set session tx_isolation='read-committed'
/etc/sysctl.conf
)查看默認值:sysctl -a
tcp相關設置:
# 三次握手listen的最大限制 net.core.somaxconn = 65535 # 默認是128 # 當網絡接受速率大於內核處理速率時,容許發送到隊列中的包數 net.core.netdev_max_backlog = 65535 # 默認是1000 # Linux隊列的最大半鏈接數(超過則丟包) net.ipv4.tcp_max_syn_backlog = 65535 # 默認是128(不適合Web服務器)
PS:這邊只是一個參考,本身能夠根據環境適當下降(最大端口數通常都是65535)
注意:若是是Web服務器,
net.ipv4.tcp_max_syn_backlog
不宜過大(容易有synflood攻擊的安全問題),net.ipv4.tcp_tw_recycle
和net.ipv4.tcp_tw_reuse
不建議開啓
加快tcp連接回收的幾個參數:
# TCP等待時間,加快tcp連接回收 net.ipv4.tcp_fin_timeout = 10 # 默認60 # 把發起關閉,但關閉沒完成的TCP關閉掉 net.ipv4.tcp_tw_recycle = 1 # 默認0(不適合Web服務器) # 容許待關閉的socket創建新的tcp net.ipv4.tcp_tw_reuse = 1 # 默認0(不適合Web服務器)
PS:net.ipv4.tcp_tw_reuse
擴展說明:主動調用closed的一方纔會在接收到對端的ACK後進入time_wait狀態
參考文章:
https://blog.csdn.net/weixin_41966991/article/details/81264095
緩存區大小的最大值和默認值:
net.core.wmem_default = 87380 # 默認212992 net.core.wmem_max = 16777216 # 默認212992 net.core.rmem_default = 87380 # 默認212992 net.core.rmem_max = 16777216 # 默認212992
PS:每一個socket
都會有一個rmem_default
大小的緩存空間(若是設置了setsockopt
則就是多少,最大不超過rmem_max
)
減小失效鏈接所佔用的系統資源:
# 對於tcp失效連接佔用系統資源的優化,加快資源回收效率 # 連接有效時間(單位s) net.ipv4.tcp_keepalive_time = 120 # 默認7200 # tcp未得到相應時重發間隔(單位s) net.ipv4.tcp_keepalive_intvl = 30 # 默認75 # 重發數量(單位s) net.ipv4.tcp_keepalive_probes = 3 # 默認9
內存相關參數:
# 共享單個共享內存下的最大值 kernel.shmmax = 4294967295 # 最大爲物理內存-1byte # 除非虛擬內存所有佔滿,不然不使用交換分區(爲了性能) # (free -m ==> Swap) vm.swappiness = 0 # 默認30
PS:kernel.shmmax
設置的足夠大,通常就是爲了容納整個innodb的緩衝池
eg:
4G = 4*1024 M = 4*1024*1024 KB = 4*1024*1024*1024 byte = 4294967296 - 1 = 4294967295
PS:unsigned int
=>[0, 2^32)
=>[0,4294967296)
=>[0,4294967295]
巧不,同樣的值
/etc/security/limit.conf
)打開文件數的限制(追加到配置後便可)
# [*|%] [soft|hard] [type_item] [value] * soft nofile 65536 * hard nofile 65535
默認值:ulimit -a
core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 3548 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 《《看這 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 3548 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
PS:通常來講是夠用了,可是一個遇到大型數據庫可能就不夠看了(多表多庫配置高)
*:全部用戶有效、soft:當前系統生效、hard:系統中所能設置的最大值、nofile:所限制的資源是打開文件的最大數、65536:數值
【重啓才生效】
/sys/block/devname/queue/scheduler
)如今默認策略就是deadline
,因此不用優化了【對數據庫支持很不錯】
PS:經過cat /sys/block/sda/queue/scheduler
查看([這個就是設置的值]
)
noop [deadline] cfq
若是不是能夠經過:echo deadline > /sys/block/sda/queue/scheduler
來設置
cfq
:會在隊列中插入一些沒必要要的請求,會致使相應時間加長,通常桌面系統用的比較多
noop
:實現了一個FIFO隊列,像電梯工做同樣對IO請求進行組織,當有一個新請求到來時會合併到最近請求以後,以此保證請求同一介質(傾向於餓死讀而利於寫)通常閃存設備
、RAM
、嵌入式系統
用的比較多
deadline
:確保了在一個截止時間內去服務請求(可調整)默認讀期限短於寫期限(防止寫操做由於不能被讀而出現餓死的現象)
Win:NTFS
,Linux:EXT3|四、XFS
Linux如今基本上都是選擇XFS
,若是是EXT3
、EXT4
還須要設置一下:/etc/fstab
(慎重)
/dev/sda1/ext4 noatime,nodiratime,data=writeback 1 1
PS:noatime
表示不記錄訪問時間,nodiratime
不記錄目錄的訪問時間(能夠減小一些寫的操做)
不一樣的日誌策略:
data=[wtiteback|ordered|journal]
- writeback:只有原數據寫入日誌,原數據寫入和數據寫入並非同步的(最快)PS:Innodb有本身的事務日誌,因此是最好的選擇
- ordered:只會記錄原數據,但提供了一些一致性的保證,在寫原數據以前會先寫數據,使他們保持一致(比writeback慢但更安全)
- journal:提供了原子日誌的一種行爲,在數據寫入到最終位置以前,將記錄到日誌中(最慢,對Innodb來講是沒有必要)
課後拓展:
TPS、併發用戶數、吞吐量關係 https://www.cnblogs.com/zhengah/p/4532156.html 針對Mysql所在linux服務器的系統優化參數 https://blog.csdn.net/qq_40999403/article/details/80666102 網絡優化之net.ipv4.tcp_tw_recycle參數 https://blog.csdn.net/chengm8/article/details/51668992 linux socket 緩存: core rmem_default rmem_max https://blog.csdn.net/penzchan/article/details/41682411 Linux上的free命令詳解、swap機制 http://www.cnblogs.com/xiaojianblogs/p/6254535.html 磁盤IO太高時的處理辦法 https://www.cnblogs.com/wjoyxt/p/4808024.html 文件系統對性能的影響 https://blog.csdn.net/qq_30353203/article/details/78197870
建議:優先從數據庫設計和SQL優化着手,而後纔是配置優化和存儲引擎的選擇,最後纔是硬件提高
設計案例:
列太多
不行,關聯太多
也不行(10個之內),不恰當的分區表
,使用了外鍵
分區表:一個服務器下,邏輯上仍是一個表,物理存儲上分紅了多個表(相似於SQLServer的水平分庫)
PS:分庫分表:物理和邏輯上都拆分紅多個表了
以前講環境的時候簡單說了下最基礎的
[mysqld] # 獨立表空間: 每個表都有一個.frm表描述文件,還有一個.ibd文件 innodb_file_per_table=on # 不對鏈接進行DNS解析(省時) skip_name_resolve=on # 配置sql_mode sql_mode='strict_trans_tables'
而後說SQL_Mode
的時候簡單說了下全局參數
和會話參數
的設置方法:MySQL的SQL_Mode修改小計
set global 參數名=參數值;
set [session] 參數名=參數值
這邊繼續說下其餘幾個影響較大的配置參數:(對於開發人員來講,簡單瞭解便可,這個是DBA的事情了)
expire_logs_days
:自動清理binlog
max_allowed_packet
:配置MySQL接收包的大小
skip_name_resolve
:禁用DNS查找(這個咱們以前說過了,主要是提速)
ip
或者ip段
或者本機host出現過的域名
進行受權
*
的是沒影響的sysdata_is_now
:保證sysdate()返回肯定性日期
statement
模式,sysdata的結果會不同,最後致使數據不一致
last_insert_id()
)Mixed
模式read_only
:通常用戶只能讀數據,只有root用戶能夠寫:
skip_slave_start
:禁用從庫(Slave
)自動恢復
sql_mode
:設置MySQL的SQL模式(這個上次說過,默認是寬鬆的檢測,這邊再補充幾個)
strict_trans_tables
:對全部支持事物類型的表作嚴格約束:
no_engine_subtitution
:建表的時候指定不可用存儲引擎會報錯only_full_group_by
:檢驗group by
語句的合法性
select count(url),name from file_records group by url;
ansi_quotes
:不容許使用雙引號來包含字符串
PS:通常SQL_Mode
是測試環境相對嚴格(strict_trans_tables,only_full_group_by,no_engine_subtitution,ansi_quotes
),線上相對寬鬆(strict_trans_tables
)
補充說下sysdate()
和now()
的區別:(看個案例就懂了)
PS:對於一個語句中調用多個函數中
now()
返回的值是執行時刻的時間,而sysdate()
返回的是調用該函數的時間
MariaDB [(none)]> select sysdate(),sleep(2),sysdate(); +---------------------+----------+---------------------+ | sysdate() | sleep(2) | sysdate() | +---------------------+----------+---------------------+ | 2019-03-28 09:09:29 | 0 | 2019-03-28 09:09:31 | +---------------------+----------+---------------------+ 1 row in set (2.001 sec) MariaDB [(none)]> select now(),sleep(2),now(); +---------------------+----------+---------------------+ | now() | sleep(2) | now() | +---------------------+----------+---------------------+ | 2019-03-28 09:09:33 | 0 | 2019-03-28 09:09:33 | +---------------------+----------+---------------------+ 1 row in set (2.000 sec)
sort_buffer_size
:每一個會話使用的排序緩衝區大小
join_buffer_size
:每一個會話使用的錶鏈接緩衝區大小
binlog_cache_size
:每一個會話未提交事物的緩衝區大小read_rnd_buffer_size
:設置索引緩衝區大小read_buffer_size
:對MyISAM全表掃描時緩衝池大小(通常都是4k的倍數)
read_buffer_size
的擴充說明:
如今基本上都是Innodb存儲引擎了,大部分的MyISAM的配置就不用管了,可是這個仍是須要配置下的
引入下臨時表知識擴展:
Memory
表MyISAM
表create temporary table tb_name(列名 類型 類型修飾符,...)
PS:如今知道爲啥配置read_buffer_size
了吧(系統使用臨時表的時候,可能會使用MyISAM
)
主要看看Innodb
的IO
相關配置
事物日誌:(總大小:Innodb_log_file_size * Innodb_log_files_in_group
)
Innodb_log_file_size
Innodb_log_files_in_group
日誌緩衝區大小:Innodb_log_buffer_size
通常日誌先寫到緩衝區中,再刷新到磁盤(通常32M~128M就夠了)
知識擴展:redo Log
內存中緩衝區的大小:(字節爲單位)
show variables like 'innodb_log_buffer_size';
show variables like 'innodb_log_files_in_group';
ib_logfile
文件(默認是2)日誌刷新頻率:Innodb_flush_log_at_trx_commit
刷新方式:Innodb_flush_method=O_DIRECT
關閉操做系統緩存(避免了操做系統和Innodb雙重緩存)
如何使用表空間:Innodb_file_per_table=1
爲每一個innodb創建一個單獨的表空間(這個基本上已經成爲通用配置了)
是否使用雙寫緩存:Innodb_doublewrite=1
(避免發生頁數據損壞)
show variables like '%double%';
設置innodb緩衝池大小:innodb_buffer_pool_size
若是都是innodb存儲引擎,這個參數的設置能夠這樣來算:(通常都是內存的
75%
)
查看命令:show global variables like 'innodb_buffer_pool_size';
PS:緩存數據和索引(直接決定了innodb性能) 課後拓展:http://www.javashuo.com/article/p-ptvyxueu-k.html
innodb緩存池實例的個數:innodb_buffer_pool_instances
PS:主要目的爲了減小資源鎖增長併發。
每一個實例的大小=總大小/實例的個數
通常來講,每一個實例大小不能小於1G,並且個數不超過8個
sync_binlog
:控制MySQL如何像磁盤中刷新binlog
tmp_table_size
and max_heap_table_size
max_connections
:設置最大鏈接數
Sleep
等待時間:通常設置爲相同值(經過鏈接參數區分是不是交互鏈接)
interactive_timeout
:設置交互鏈接的timeout時間wait_timeout
:設置非交互鏈接的timeout時間pt-config-diff
使用參考:pt-config-diff u=root,p=pass,h=localhost /etc/my.conf
eg:比較配置文件和服務器配置
pt-config-diff /etc/my.cnf h=localhost --user=root --password=pass 3 config differences Variable /etc/my.cnf mariadb2 ========================= =========== ======== max_connect_errors 2 100 rpl_semi_sync_master_e... 1 OFF server_id 101 102
課後拓展:https://www.cndba.cn/leo1990/article/2789
常見存儲引擎:
frm、MYD、MYI
Innodb
:事物級存儲引擎,支持行級鎖和事物ACID特性
frm、ibd
Memory
:表結構保存在磁盤文件中,表內容存儲在內存中
CSV
:通常都是做爲中間表
.frm
(存儲表結構)、.arz
(存儲數據)insert
和select
操做適合場景:日誌類
(省空間)逆天點評:除非你有100%的理由,不然全選innodb
,特別不建議混合使用
Memory存儲引擎:
Hash
和BTree
兩種索引
create index ix_name using btree on tb_name(字段,...)
Text
和Blog
等大字段類型
varchar(100)
==等價於==> char(100)
max_heap_table_size
決定(默認16M)
數據易丟失,要保證數據可再生
)
PS:如今基本上都是redis了,若是不使用redis的小項目能夠考慮(eg:官網、博客...)
文章拓展:
OLAP、OLTP的介紹和比較 https://www.cnblogs.com/hhandbibi/p/7118740.html now()與sysdate() http://blog.itpub.net/22664653/viewspace-752576/ https://stackoverflow.com/questions/24137752/difference-between-now-sysdate-current-date-in-mysql binlog三種模式的區別(row,statement,mixed) https://blog.csdn.net/keda8997110/article/details/50895171/ MySQL-重作日誌 redo log -原理 https://www.cnblogs.com/cuisi/p/6525077.html 詳細分析MySQL事務日誌(redo log和undo log) https://www.cnblogs.com/f-ck-need-u/archive/2018/05/08/9010872.html innodb_flush_method的性能差別與File I/O https://blog.csdn.net/melody_mr/article/details/48626685 InnoDB關鍵特性之double write https://www.cnblogs.com/geaozhang/p/7241744.html
上節在最後的時候說了下存儲引擎,這邊簡單回顧下:
存儲引擎 | 是否支持事物 | 文字說明 |
---|---|---|
MyISAM |
不支持 | MySQL5.6之前的默認存儲引擎 |
CSV |
不支持 | 用CSV格式來存儲數據(通常當中間表) |
Archive |
不支持 | 只能查詢和添加數據(通常記錄日誌用) |
Memory |
不支持 | 數據只存儲在內存中(容易丟失) |
innodb |
支持(行級鎖) | 如今基本上都使用這個 |
NDB |
支持(行級鎖) | MySQL集羣才使用(內存型,數據會持久化一份) |
補充說明:
Archive
存儲引擎的數據會用zlib
來壓縮,並且只支持在自增ID上添加索引NDB
存儲引擎的數據存儲在磁盤中(熱數據存儲在內存中),支持Ttree索引和集羣
提一個場景:innodb
表沒法在線修改表結構的時候怎麼解決?
先看下Innodb不支持在線修改表結構
都有哪些狀況:(主要從性能方面考慮)
全文索引
和添加空間索引
(MySQL5.6
之前版本不支持)
create fulltext index name on table(列,...);
alter table geom add spatial index(g);
alter table 表名 drop primary key
alter table 表名 add column id int auto_increment primary key
alter table 表名 modify 列名 類型 類型修飾符
alter table 表名 character set=utf8mb4
PS:DDL不能併發執行(表級鎖)長時間的DDL操做會致使主從不一致
DDL無法進行資源限制,表數據多了容易佔用大量存儲IO空間(空間不夠就容易執行失敗)
安裝:yum install percona-toolkit
or apt-get install percona-toolkit
PS:離線包:
https://www.percona.com/downloads/percona-toolkit/LATEST/
命令:pt-online-schema-change 選項 D=數據庫,t=表名,u=用戶名,p=密碼
原理:先建立一個類型修改完的表,而後把舊錶數據copy過去,而後刪除舊錶並重命名新表
查看幫助文檔:pt-online-schema-change --help | more
官方文檔:https://www.percona.com/doc/percona-toolkit/LATEST/pt-online-schema-change.html
PS:通常就--alter
和--charset
用的比較多(--execute
表明執行)
經常使用:pt-online-schema-change --alter "DDL語句" --execute D=數據庫,t=表名,u=用戶名,p=密碼
eg:添加新列:
pt-online-schema-change --alter "add 列名 類型" --execute D=數據庫,t=表名,u=用戶名,p=密碼
知識回顧:
alter table tb_name add 列名 數據類型 修飾符 [first | after 列名];
[first | after 列名]
alter table tb_name change 舊列名 新列名 類型 類型修飾符
alter table tb_name modify 列名 類型 類型修飾符
alter table tb_name alter 列名 set default df_value
alter table tb_name drop 字段名
寫在前面的概念:排它鎖(別名:獨佔鎖、寫鎖)、共享鎖(別名:讀鎖)
事物4大特性:A(原子性)C(一致性)I(隔離性)D(持久性)
innodb事務日誌主要就是redo log
(重作日誌)和undo log
(回滾日誌)
事物特性 | innodb實現方式 |
---|---|
原子性(A) | 回滾日誌(undo log ):用於記錄數據修改前的狀態 |
一致性(C) | 重作日誌(redo log ):用於記錄數據修改後的狀態 |
隔離性(I) | 鎖(lock ):用於資源隔離(共享鎖 + 排他鎖) |
持久性(D) | 重作日誌(redo log ) + 回滾日誌(undo log ) |
我畫個轉帳案例:
讀
操做是否會阻塞寫
操做?通常狀況下:查詢
須要對資源添加共享鎖(讀鎖) | 修改
須要對資源添加排它鎖(寫鎖)
是否兼容 | 寫鎖 |
讀鎖 |
---|---|---|
寫鎖 |
不兼容 | 不兼容 |
讀鎖 |
不兼容 | 兼容 |
PS:共享鎖和共享鎖之間是能夠共存的(讀的多併發)理論上講讀操做和寫操做應該相互阻塞
而innodb
看起來卻彷彿打破了這個常規,看個案例:
1.啓動一個事物,可是不提交
2.在另外一個鏈接中查詢
PS:理論上獨佔鎖沒提交時是不能讀操做的,但innodb
作了優化,會查詢undo log
(未修改前的數據)中的記錄來提升併發性
3.提交事物後再查詢,這時候就看到更新後的數據了
PS:這個就是innodb的MVCC
(多版本併發控制)
知識拓展:
【推薦】Mysql的InnoDB事務多版本併發控制如何實現(MVCC) https://www.cnblogs.com/aspirant/p/6920987.html https://blog.csdn.net/u013007900/article/details/78641913 https://www.cnblogs.com/dongqingswt/p/3460440.html https://www.jianshu.com/p/a3d49f7507ff https://www.jianshu.com/p/a03e15e82121 https://www.jianshu.com/p/5a9c1e487ddd 基於mysql全文索引的深刻理解 https://www.cnblogs.com/dreamworlds/p/5462018.html 【推薦】MySQL中的全文索引(InnoDB存儲引擎) https://www.jianshu.com/p/645402711dac innodb的存儲結構 https://www.cnblogs.com/janehoo/p/6202240.html 深刻淺出空間索引:爲何須要空間索引 https://www.cnblogs.com/mafeng/p/7909426.html 常見的空間索引方法 https://blog.csdn.net/Amesteur/article/details/80392679 【推薦】pt-online-schema-change解讀 https://www.cnblogs.com/xiaoyanger/p/6043986.html pt-online-schema-change使用說明、限制與比較 https://www.cnblogs.com/erisen/p/5971416.html pt-online-schema-change使用注意要點 https://www.jianshu.com/p/84af8b8f040b 詳細分析MySQL事務日誌(redo log和undo log) https://www.cnblogs.com/f-ck-need-u/archive/2018/05/08/9010872.html
以前在SQL環境篇的時候簡單提了一下權限設置(點我回顧),如今再說說經常使用的權限知識:
用戶組成格式:用戶名@可訪問控制的列表
UTF-8
爲例:1英文字符 = 1字節,1中文 = 3字節%
:全部ip均可訪問(通常都這麼幹的,數據比較重要的推薦使用第二種)192.168.1.%
:192.168.1
網段的ip均可以訪問
localhost
(數據庫本地服務器不能訪問)localhost
:只能經過數據庫服務器進行本地訪問1.建立命令:create user 用戶名@ip identified by '密碼';
PS:可使用
\h create user
來查看幫助文檔
2.查看當前用戶:select user();
PS:MariaDB
查看當前數據庫有哪些用戶:select user,password,host from mysql.user;
MySQL:
select user,authentication_string,host from mysql.user;
3.修改密碼:alter user user() identified by '密碼';
4.另類思路:我通常都是直接在表中插入數據(MySQL是authentication_string
)
eg:
insert into mysql.user(user,host,password) values("用戶名","%",password("密碼"));
PS:修改密碼:
update mysql.user set
password=password('新密碼') where user='用戶名';
知識拓展:ERROR 1045 (28000): Access denied for user 'mysql'@'localhost'
權限類別 | 語句 | 說明文字 |
---|---|---|
admin |
create user |
建立新用戶權限 |
- | grant option |
爲用戶設置權限 |
- | super |
設置服務器權限 |
DDL |
create |
建立數據庫和表 |
- | alter |
修改表結構權限 |
- | index |
建立和刪除索引 |
- | drop |
刪除數據庫和表 |
DML |
select |
查詢表數據權限 |
- | insert |
插入表數據權限 |
- | update |
刪除表數據權限 |
- | execute |
可執行存儲過程 |
- | delete |
刪除表數據權限 |
補充說明:super
:如設置全局變量等系統語句,通常DBA會有這個權限
PS:MariaDB查看數據庫支持哪些權限:show privileges;
權限這個東西你們都懂,通常都是最小權限
受權命令以下:grant 權限列表 on 數據庫.表 to 用戶名@ip
PS:開發的時候可能爲了省事這麼設置:
grant all [privileges] on 數據庫.* to 用戶名@'%';
正規點通常這麼設置:
grant select,insert,update on 數據庫.* to 用戶名@ip
grant select,insert,update,index,alter,create on 數據庫.* to 用戶名@ip段
PS:查看當前用戶權限:show grants for 用戶名;
,刷新數據庫權限:flush privileges;
之前能夠在受權的時候直接建立用戶(加一段
identified by '密碼'
),新版本好像分開了
命令以下:revoke 權限列表 on 數據庫.表 from 用戶名@ip
eg:
revoke create,alter,delete from django.* from dnt@'%'
(是from
而不是on
)
這個瞭解便可,我也是剛從DBA朋友那邊瞭解到的知識(MySQL8.0
),基本上用不到的,簡單羅列下規範:
設置前三次使用過的密碼不能再使用:create user@'%'identified by '密碼' password history 3;
PS:設置用戶密碼過時:alter user 用戶名@ip password expire;
經典問題:如何從一個實例遷移數據庫帳號到另外一個實例?
官方文檔:https://www.percona.com/doc/percona-toolkit/LATEST/pt-show-grants.html
數據庫備份下,而後在新環境中恢復
而後導出用戶建立和受權語句:eg:pt-show-grants -u=root,-p=密碼,-h=服務器地址 -P=3306
擴展文章:pt-show-grants的使用(eg:
pt-show-grants --host=192.168.36.123 --port=3306 --user=root --password=密碼
)
生成的腳本大體是這樣的:(把腳本放新服務器中執行便可)
CREATE USER IF NOT EXISTS 'mysql.sys'@'localhost'; ALTER USER 'mysql.sys'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT LOCK;GRANT SELECT ON `sys`.`sys_config` TO 'mysql.sys'@'localhost'; GRANT TRIGGER ON `sys`.* TO 'mysql.sys'@'localhost'; GRANT USAGE ON *.* TO 'mysql.sys'@'localhost'; -- Grants for 'root'@'%' CREATE USER IF NOT EXISTS 'root'@'%'; ALTER USER 'root'@'%' IDENTIFIED WITH 'mysql_native_password' AS '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' REQUIRE NONE PASSWORD EXPI RE DEFAULT ACCOUNT UNLOCK;GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
可使用上面的方法,可是須要使用mysql_upgrade
升級下系統表(適用:低版本到高版本)可是推薦使用生成SQL腳本