Mardorab-10.2.19がインストールされたFedora29にjoomla-3.9およびApache-2.4.34システムがあり、検索コンテンツを含むテーブルが非常に大きい。いくつかは1.2GBより大きく、1つは5.5GBより大きいです。記事の削除には非常に時間がかかります。
それが実行されているシステムはIntel(R)Xeon(R)CPU E5-2623 v3 @ 3.00GHzで、64GBのRAMとRAID5 SSDを搭載しています。他にアクティビティはありません。 。
パフォーマンスを向上させるためのオプションはありますか?基本的なmariadbのチューニングをいくつか行いましたが、データベース自体にできることは実際にはあまりありません。
これはガレラの目的ですか?データベースをramdiskに入れると役に立ちますか?
AWSへの移行には何が関係していますか?
Ext4以外の別のファイルシステムに変更すると、かなりの違いが生じますか?
RAID5を使用せずに簡単に再構築できるため、検索テーブルだけを別のSSDに置くことを考えていましたが、他のデータベースからそれらを分離する方法がわかりませんでした。
これは、このシステムのmy.cnf構成です。パフォーマンスを改善するために行う他のチューニング変更はありますか?
[client]
port = 3306
socket = /var/lib/mysql/mysql.sock
[mysqld]
port = 3306
socket = /var/lib/mysql/mysql.sock
skip-external-locking
key_buffer_size = 256M
max_allowed_packet = 16M
table_open_cache = 256
sort_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 4M
myisam_sort_buffer_size = 64M
thread_cache_size = 8
query_cache_size= 16M
thread_concurrency = 8
relay_log_space_limit = 500M
relay_log_purge = 1
log-slave-updates = 1
max_heap_table_size = 256M
tmp_table_size = 256M
relay-log=bwimail01-relay-bin
log_bin = /var/log/mariadb/mysql-bin.log
expire_logs_days = 5
max_binlog_size = 100M
plugin_load=server_audit=server_audit.so
server_audit_events=connect,query
server_audit_file_path = /var/log/mariadb/server_audit.log
server_audit_file_rotate_size = 1G
server_audit_file_rotations = 1
slow-query-log = 1
slow-query-log-file = /var/log/mariadb/mariadb-slow.log
long_query_time = 1
log_error = /var/log/mariadb/mariadb-error.log
binlog_format=mixed
server-id = 5
report-Host=bwimail01.example.com
innodb_data_home_dir = /var/lib/mysql
innodb_defragment=1
innodb_file_per_table
innodb_flush_log_at_trx_commit = 2
innodb_data_file_path = ibdata1:10M:autoextend:max:500M
innodb_buffer_pool_size=850M
innodb_log_file_size = 64M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 2
innodb_flush_method=O_DIRECT
innodb_lock_wait_timeout = 50
[mysqldump]
quick
max_allowed_packet = 16M
[mysql]
no-auto-rehash
[myisamchk]
key_buffer_size = 128M
sort_buffer_size = 128M
read_buffer = 2M
write_buffer = 2M
[mysqlhotcopy]
interactive-timeout
編集:これは「show create table Finder_links」です
Finder_links | CREATE TABLE `Finder_links` (
`link_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`url` varchar(255) NOT NULL,
`route` varchar(255) NOT NULL,
`title` varchar(400) DEFAULT NULL,
`description` text DEFAULT NULL,
`indexdate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`md5sum` varchar(32) DEFAULT NULL,
`published` tinyint(1) NOT NULL DEFAULT 1,
`state` int(5) DEFAULT 1,
`access` int(5) DEFAULT 0,
`language` varchar(8) NOT NULL,
`publish_start_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`publish_end_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`start_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`end_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`list_price` double unsigned NOT NULL DEFAULT 0,
`sale_price` double unsigned NOT NULL DEFAULT 0,
`type_id` int(11) NOT NULL,
`object` mediumblob NOT NULL,
PRIMARY KEY (`link_id`),
KEY `idx_type` (`type_id`),
KEY `idx_title` (`title`(100)),
KEY `idx_md5` (`md5sum`),
KEY `idx_url` (`url`(75)),
KEY `idx_published_list`
(`published`,`state`,`access`,`publish_start_date`,`publish_end_date`,`list_price`),
KEY `idx_published_sale`
(`published`,`state`,`access`,`publish_start_date`,`publish_end_date`,`sal e_price`)
) ENGINE=InnoDB AUTO_INCREMENT=62705 DEFAULT CHARSET=utf8mb4
問題の一部は、これがjoomlaの一部であるため、テーブルの編成方法、スキーマを改善するために行うことができる変更、またはスキーマへの書き込みを編成する方法を実際には制御できないことです。
次のような遅いクエリがたくさんあるようです:
INSERT IGNORE INTO `xu5gc_Finder_terms`
(`term`, `stem`, `common`, `phrase`, `weight`, `soundex`, `language`)
SELECT ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight,
SOUNDEX(ta.term), ta.language
FROM `xu5gc_Finder_tokens_aggregate` AS ta
WHERE ta.term_id = 0
GROUP BY ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight,
SOUNDEX(ta.term), ta.language;
INSERT INTO `xu5gc_Finder_tokens_aggregate`
(`term_id`, `map_suffix`,
`term`, `stem`, `common`, `phrase`, `term_weight`, `context`,
`context_weight`, `total_weight`, `language`)
SELECT COALESCE(t.term_id, 0), '', t1.term, t1.stem, t1.common,
t1.phrase, t1.weight, t1.context,
ROUND( t1.weight * COUNT( t2.term ) * 0.700000, 8 ) AS context_weight,
0, t1.language
FROM (
SELECT DISTINCT t1.term, t1.stem, t1.common, t1.phrase, t1.weight,
t1.context, t1.language
FROM `xu5gc_Finder_tokens` AS t1
WHERE t1.context = 2
) AS t1
JOIN `xu5gc_Finder_tokens` AS t2 ON t2.term = t1.term
LEFT JOIN `xu5gc_Finder_terms` AS t ON t.term = t1.term
WHERE t2.context = 2
GROUP BY t1.term, t.term_id, t1.term, t1.stem, t1.common,
t1.phrase, t1.weight, t1.context, t1.language
ORDER BY t1.term DESC;
そして
UPDATE `xu5gc_Finder_terms` AS t
INNER JOIN `xu5gc_Finder_tokens_aggregate` AS ta
ON ta.term_id = t.term_id
SET t.`links` = t.links + 1;
SET timestamp=1546570831;
SELECT DISTINCT t.term_id AS id, t.term AS term
FROM xu5gc_Finder_terms AS t
WHERE t.soundex = SOUNDEX('2018 2594-1')
AND t.phrase = 1;
編集:要求された情報をさらに追加します。現在、約24時間稼働していますが、これは開発システムであるため、現在あまり活動がありません。
グローバル変数を表示
https://Pastebin.com/W0BPKtU5
GLOBALKステータスを表示
https://Pastebin.com/gB0AQut6
ファインダーテーブル(SHOW INDEX FROMおよびEXPLAIN)
xu5gc_Finder_termsは5.4GBテーブルです
https://Pastebin.com/rJxts9Sp
MySQLTuner-Perl-master
https://Pastebin.com/AW6F0uMj
Mariadbエラーログ(/var/log/mariadb/mariadb-error.log)
https://Pastebin.com/EE8Q0k1D
いくつかの画像があると役立つと思いました。他の統計情報が役立つかどうか教えてください。
編集:追加されたulimit出力(ルートとして):
# ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 128545
max locked memory (kbytes, -l) 16384
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) 128545
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
変数とグローバルステータスの分析:
観測:
より重要な問題:
innodb_io_capacity
は、おそらく1000以上に増やすことができます。
このサーバーでは、Galeraはオフになっています。制作のためにオンにしていますか?通常のレプリケーションを使用している場合は、sync_binlog = ON
。
6テーブルスキャン/秒。クエリの半分にはテーブルスキャンが含まれます。クエリをもう少し見てみましょう。 (1時間あたり79回のソートマージパスのみ。)
MySQL Clusterを使用していますか? (Handler_discoverが表示されます。)
(ありがとう:slowlogの適切な設定。)
innodb_use_atomic_writes
-RAIDコントローラハードウェアですか?どんなブランド?アトミック16KB書き込みをサポートしていますか?
engine_condition_pushdown = off
- なぜ?
詳細と他の観察:
( innodb_buffer_pool_size / _ram ) = 15360M / 65536M = 23.4%
-RAMの%がInnoDB buffer_poolに使用されます(ただし、価値のあるものにするための十分なデータがありません)
( ( Binlog_commits - Binlog_group_commits ) / Binlog_group_commits ) = ( 74938 - 74938 ) / 74938 = 0
-並行して実行できるCOMMITの割合-マスターのbinlog_commit_wait_usecまたはbinlog_commit_wait_count、あるいはその両方を増やします。
( innodb_page_cleaners / innodb_buffer_pool_instances ) = 4 / 15 = 0.267
-page_cleaners-innodb_page_cleanersをinnodb_buffer_pool_instancesに設定することをお勧めします
( innodb_lru_scan_depth ) = 1,024
-「InnoDB:page_cleaner:1000ms意図したループにかかった...」はlru_scan_depthを下げることで修正できる
( Innodb_buffer_pool_pages_free * 16384 / innodb_buffer_pool_size ) = 705,616 * 16384 / 15360M = 71.8%
-バッファプールフリー-buffer_pool_sizeはワーキングセットよりも大きい。それを減らすことができます
( Innodb_buffer_pool_pages_free / Innodb_buffer_pool_pages_total ) = 705,616 / 983040 = 71.8%
-現在使用されていないbuffer_poolの部分-innodb_buffer_pool_sizeが必要以上に大きいですか?
( Innodb_buffer_pool_bytes_data / innodb_buffer_pool_size ) = 4,475,404,288 / 15360M = 27.8%
-データが占めるバッファープールの割合-小さなパーセントmayは、buffer_poolが不必要に大きいことを示します。
( Uptime / 60 * innodb_log_file_size / Innodb_os_log_written ) = 74,340 / 60 * 1024M / 465657856 = 2,856
-InnoDBログローテーション間の分5.6.8以降、これは動的に変更できます。 my.cnfも必ず変更してください。 -(ローテーション間の60分の推奨はやや恣意的です。)innodb_log_file_sizeを調整します。 (AWSでは変更できません。)
( innodb_io_capacity ) = 200
-ディスク上で実行可能な1秒あたりのI/O操作。遅いドライブの場合は100。ドライブを回転させる場合は200。 SSDの場合は1000〜2000。 RAID係数を掛けます。
( sync_binlog ) = 0
-追加のセキュリティのために1を使用します。I/ Oのコストは= 1の場合、多くの「クエリの終了」につながる可能性があります。 = 0は「不可能な位置でのバイナリログ」につながり、クラッシュでトランザクションを失う可能性がありますが、より高速です。
( innodb_print_all_deadlocks ) = innodb_print_all_deadlocks = OFF
-すべてのデッドロックをログに記録するかどうか。 -デッドロックに悩まされている場合は、これをオンにします。注意:デッドロックが多い場合、ディスクに大量に書き込まれる可能性があります。
( join_buffer_size / _ram ) = 1M / 65536M = 0.00%
-スレッドごとに0-N。 JOINを高速化する可能性があります(クエリ/インデックスを修正する方が良い)(すべてのエンジン)インデックススキャン、範囲インデックススキャン、全テーブルスキャン、各全JOINなどに使用されます。サイズが大きい場合は、join_buffer_sizeを減らしてメモリ負荷を回避します。 RAMの1%未満を推奨します。小さい場合は、RAMの0.01%に増やして、一部のクエリを改善します。
( net_buffer_length / max_allowed_packet ) = 16,384 / 16M = 0.10%
( local_infile ) = local_infile = ON
-local_infile = ONは潜在的なセキュリティ問題です
( bulk_insert_buffer_size / _ram ) = 8M / 65536M = 0.01%
-複数行のINSERTおよびLOAD DATAのバッファー-小さすぎると、このような操作が妨げられる可能性があります。
( tmp_table_size ) = 256M
-[〜#〜]メモリのサイズの制限[〜#〜]SELECTをサポートするために使用される一時テーブル-tmp_table_sizeを減らして回避RAMが不足しています。おそらく64M以下です。
( (Com_insert + Com_update + Com_delete + Com_replace) / Com_commit ) = (20260 + 69883 + 2901 + 0) / 62678 = 1.48
-コミットごとのステートメント(すべてのInnoDBを想定)-低:トランザクションでクエリをグループ化するのに役立つ場合があります。
( Select_scan ) = 448,754 / 74340 = 6 /sec
-全テーブルスキャン-インデックスを追加する/クエリを最適化する(小さなテーブルでない限り)
( Select_scan / Com_select ) = 448,754 / 871456 = 51.5%
-全表スキャンを実行する選択の%。 (ストアドルーチンにだまされる可能性があります。)-インデックスを追加する/クエリを最適化する
( relay_log_space_limit ) = 500M
-スレーブのリレーログの最大合計サイズ。 (0 =無制限)-制限を設ける根拠について説明しましょう。
( binlog_format ) = binlog_format = MIXED
-STATEMENT/ROW/MIXED。 ROWが推奨されます。デフォルトになる場合があります。
( wsrep_log_conflicts ) = wsrep_log_conflicts = OFF
-COMMIT中にデッドロックの競合が発生した場合、このフラグが役立ちます。
( back_log / max_connections ) = 80 / 151 = 53.0%
異常に小さい:
Handler_read_next / Handler_read_key = 0.647
Innodb_secondary_index_triggered_cluster_reads = 7.8MB
Rows_tmp_read = 2.3MB
eq_range_index_dive_limit = 0
innodb_log_block_size = 0
innodb_max_bitmap_file_size = 0
innodb_max_changed_pages = 0
innodb_mirrored_log_groups = 0
innodb_sched_priority_cleaner = 0
innodb_show_locks_held = 0
lock_wait_timeout = 86400
slave_net_timeout = 60
異常に大きい:
Com_show_binlogs = 25 /HR
Com_show_engine_status = 26 /HR
Com_show_plugins = 25 /HR
Com_show_slave_hosts = 0.15 /HR
Com_show_slave_status = 0.04 /sec
Handler_discover = 27 /HR
Innodb_buffer_pool_pages_flushed / max(Questions, Queries) = 1
Innodb_buffer_pool_pages_free = 705,616
Innodb_system_rows_deleted = 0.81 /sec
Innodb_system_rows_inserted = 0.81 /sec
Innodb_system_rows_read = 60,203
Opened_plugin_libraries = 0.097 /HR
Performance_schema_file_classes_lost = 1
Slave_received_heartbeats = 656
Slaves_running = 1
group_concat_max_len = 1MB
innodb_adaptive_hash_index_partitions = 8
max_relay_log_size = 100MB
異常な文字列:
Slave_running = ON
binlog_annotate_row_events = ON
innodb_buffer_pool_dump_at_shutdown = ON
innodb_buffer_pool_load_at_startup = ON
innodb_corrupt_table_action = deprecated
innodb_data_home_dir = /var/lib/mysql
innodb_defragment = ON
innodb_fast_shutdown = 1
innodb_file_format = Barracuda
innodb_file_format_max = Barracuda
innodb_large_prefix = ON
innodb_locking_fake_changes = OFF
innodb_undo_directory = ./
innodb_use_atomic_writes = ON
innodb_use_global_flush_log_at_trx_commit = OFF
innodb_use_trim = ON
log_slow_admin_statements = ON
log_slow_slave_statements = ON
myisam_stats_method = NULLS_UNEQUAL
opt_s__engine_condition_pushdown = off
replicate_annotate_row_events = ON
遅いクエリに関するヒント。これは、提案の簡単なリスト、_CREATE TABLE
_であり、テーブルサイズが役立つ場合があります。
_INSERT...SELECT
_は繰り返し行われていますか?段階的に行うことはできますか?同様に、今日のデータを今日はコピーしますが、明日はコピーしませんか?
_xu5gc_Finder_tokens_aggregate
_-SELECT
で処理するのではなく、別の列にSOUNDEX(term)
を事前計算することを検討してください。
_SELECT ... FROM xu5gc_Finder_tokens_aggregate
_テーブル全体を読み取り、一時ファイルを作成してから、_GROUP BY
_を実行する必要があります。それだけの出力が必要かどうかを考え直してください。待つ!なぜ_GROUP BY
_があるのですか?集合体はありませんか?
WHERE t.soundex = SOUNDEX('2018 2594-1') AND t.phrase = 1
にはINDEX(phrase, soundex)
が必要です(どちらの順序でも)。
_JOIN t2 ON t2.term = t1.term ... WHERE t2.context = 2
_ mayコンテキストが同じであるため、_JOIN t2 ON t2.term = t1.term AND t2.context = t1.context
_のように機能します。次に、INDEX(term, context)
(どちらの順序でも)がおそらく有益です。
term
と_term_id
_は1:1ですか?グループ化と結合は、いつ使用するかについて一貫していないようです。 may _term_id
_を削除してterm
を_PRIMARY KEY
_に昇格する価値はありますか?
私のマントラ:「パフォーマンスの問題でハードウェアをスローできるのは1回だけです。ソフトウェアソリューションを探すことをお勧めします。」
電源障害(または他のクラッシュまたはROLLBACK
の必要性)が発生した場合に古い行を保存するため、多数の行を削除するとコストがかかります。
行数が少ない場合、適切なインデックスがない可能性がありますか? SHOW CREATE TABLE
およびDELETE
ステートメントを提供してください。
行数が多い場合は、チャンク単位で行うのが最適です。
これが1か月以上経過したレコードを削除するなどの反復的なプロセスである場合、PARTITION BY RANGE
は非常に有益です。
最後の2つのケースは両方ともカバーされています here 。
通常、「パフォーマンスの問題を回避することはできません」。ただし、適切に調整されていないものが1つまたは2つあります。
64GB of RAM with a 5.5GB table and innodb_buffer_pool_size=850M
その設定は、利用可能なRAMの70%まで上げることができます。しかし、10Gでもメリットがあります。
再、あなたの黙想:
RAMディスクを使用しないしない。
AWSが役立つかどうかはわかりません。彼らはbuffer_poolを適切なサイズに設定したはずですが、他の問題があるかもしれません。
Galeraの主な用途はHA(高可用性)であり、ほとんど問題なくサーバーのクラッシュに耐えます。
別のファイルシステムは「かなり役立つ」とは言えません。
SSDを搭載したRAID5は、間違いなく最良の方法です。それから離れないでください。バッテリーバックアップ式ライトキャッシュを備えたハードウェアRAIDコントローラーが含まれているといいのですが?テーブル(ファイル)の配置を手動で行うよりも、RAIDにアクセスを処理させるほうが良いです。
クエリ
望ましいインデックス:
xu5gc_Finder_tokens_aggregate: INDEX(term_id) -- for insert..select #1 & Update
xu5gc_Finder_tokens: INDEX(context, term) -- in that order.
xu5gc_Finder_terms: INDEX(term)
xu5gc_Finder_terms: INDEX(term_id)
xu5gc_Finder_terms: INDEX(phase, soundex, -- first, in either order
term, term_id) -- in either order (for 'covering')
(SHOW CREATE TABLE
を参照すると役立つ場合があります。)
1秒あたりのレート= my.cnf [mysqld]セクションで考慮すべきRPSの提案
innodb_io_capacity=1900 # from 200 to enable SSD additional IOPS
read_rnd_buffer_size=512K # ~4M to reduce handler_read_rnd_next RPS of 7,601
innodb_lru_scan_depth=100 # from 1024 to reduce CPU busy cycles 90% for this function
innodb_log_buffer_size=16M # from 8M to support ~ 30 minutes in buffer before WD
table_definition_cache=500 # from 500 to reduce opened_table_definitions count
Ulimit -aの結果の投稿を楽しみにしています。お使いのOSが、MySQLがテーブル管理に使用できるオープンファイルハンドルの数を制限している可能性があります。
その他の提案については、私のプロフィールをご覧ください。ネットワークプロフィールには連絡先情報があります。
2019年1月13日02:20アレックス、正解です。1024のオープンファイルは、アクティビティのレベルに対して低すぎます。
Linuxコマンドプロンプトからulimit -aを検討するための提案
ulimit -n 16384#より多くのOSファイルハンドルをアクティブにできるようにする1024から。
上記はLinux OSで動的です。停止/開始サービスはハンドルにアクセスできます。
OSのシャットダウン/再起動後もこれを維持するには、このURLで同様のOSの手順を確認してください
これらの手順ではfile-maxに500000を設定しています。今のところ容量を16384に設定してください。
ulimitは16384に設定してください。これにより、MySQLはリクエストされた1206を使用できるようになります
他のアプリ用のスペアがあります
https://glassonionblog.wordpress.com/2013/01/27/increase-ulimit-and-file-descriptors-limit/
Skypeでの連絡を楽しみにしています。私のSkype IDは[email protected]です。最新のコメントをありがとうございます。