GHTorrentのデータベースダンプ(GitHubメタデータを含むCSVファイル)を復元しようとしています。 commits
テーブルには891百万行以上、project_commits
には54億行以上あります。これらのテーブルは非常に大きいため、外部キーチェックをオフにしてLOAD DATA INFILE
を使用してロードする必要がありました。 MyISAM
エンジンを使用しています。テーブルへのレコードのインポートが完了した後、これらのテーブルのインデックスを作成しようとしています。
commits
テーブルに対して次のmysqlコマンドを実行していますが、12時間以上で完了しませんでした。
CREATE UNIQUE INDEX `sha` ON `ghtorrent_restore`.`commits` (`sha` ASC) COMMENT '';
Commitsテーブルは次のようになります。
遅いインデックス作成に関する他のstackexchangeの質問を読み、my.cnf
ディレクトリの/etc/mysql
ファイルに以下を設定しました。
[mysqld]
bulk_insert_buffer_size=1G
myisam_sort_buffer_size=8G
key_buffer_size=6G
sort_buffer_size=10M
前のコマンドは時間内に終了しなかったので、コンソールからctrl + zを使用して停止する必要がありました。 MySQLワークベンチでテーブルをチェックしましたが、破損しているようには見えませんが、インデックスの長さとして36GBを示しています。
このテーブルのインポートには約25分かかったので、インデックス作成には1時間以上はかからないと思いますが、「create unique index」コマンドを約2時間実行しても進行の兆候はありません。
コマンドを実行すると、mysqldが大量のCPUを使用し、メモリを使用し続けます。 6GBに達した後は、アクティブでなくなり、ほとんど何もしていません。
これは、コマンド(次の図で選択したもの)がmysqlワークベンチからどのように見えるかを示しています。
Mysql 5.7.22-0ubuntu0.16.04.1を16GB RAMのLinux Mint 17.03マシンで実行しています。
私は上級ユーザーではないので、どんな助けも大いに役立ちます。
更新[Wilson H.の提案どおり]:
my.cnfファイル[06/05/2018 01:06]
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
[mysqld]
secure-file-priv = ""
[mysqld]
bulk_insert_buffer_size=1G
myisam_sort_buffer_size=8G
key_buffer_size=6G
sort_buffer_size=10M
bufferとcacheに関連する変数。
Mysqlのインストールで他に何も変更していません。 Mysqldは、システムで使用可能な合計16GBのRAMのうち、テーブルごとに異なるメモリ量を使用します。 mysql以外にCPU /メモリを大量に消費するアプリケーションは実行していません。
興味深い観察:他のテーブルを使用したいくつかのテストでは、行数の増加に対して時間の増加が示されています。傾向は多項式に見えます。
次の統計は、上の図の最後のmysqlコマンドが実行されている間にキャプチャされました(つまり、テーブル 'projects'のインデックス作成)。
ulimit -a:
df -h:
Update 2: 'commits'テーブルでのインデックスの作成が完了していないため、他のテーブルを試し、最後に 'project_commits'テーブルでインデックス付けを試みました昨夜寝る前に。驚いたことに、インデックス作成を完了するのに18分しかかからなかった。
追加の変更は行わず、「コミット」テーブルが終了しない理由がわかりません。 'commits'テーブルで再度インデックス作成を実行して、それがどの程度進んでいるかを確認します。
更新3:
'SHOW CREATE TABLE commits;'
CREATE TABLE `commits` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`sha` varchar(40) DEFAULT NULL,
`author_id` int(11) DEFAULT NULL,
`committer_id` int(11) DEFAULT NULL,
`project_id` int(11) DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `commits_ibfk_1` (`author_id`),
KEY `commits_ibfk_2` (`committer_id`),
KEY `commits_ibfk_3` (`project_id`)
) ENGINE=MyISAM AUTO_INCREMENT=922093754 DEFAULT CHARSET=utf8
ボトムライン:
「コミット」テーブルを除くすべてのテーブルのインデックス作成が完了します(つまり、次のコマンドは実行を完了していません)。
CREATE UNIQUE INDEX `sha` ON `ghtorrent_restore`.`commits` (`sha` ASC) COMMENT '';
8億9100万行から約19000行をカウントするクエリ(下図を参照)を実行すると、約76秒かかります。 Core i707700HQ CPU @ 2.8 GHz x 4、16 GB DDR4 Ramを搭載したコンピューターがあり、データベースが7200RPMのHDDにインストールされている場合、今回は高すぎますか? 76秒は、 'commits'テーブルでインデックスが正しく機能していないことを示していますか?このクエリは、影響を避けるためにコンピューターの起動直後に実行されたことに注意してくださいバッファから。
複数の問題があります。
922MのAuto_incは、_INT SIGNED
_の20億の制限の半分です。次のALTER
中に_INT UNSIGNED
_(40億制限)に変更することを提案します。
MyISAMはディスク領域を節約しますが、それ以外はInnoDBよりも「悪い」です。注:InnoDBに変更するには、いくつかの設定を変更する必要があります。
MyISAMは_FOREIGN KEYS
_を無視します。
sha
がSHA-1ハッシュの場合、インデックス作成はひどいです。
sha
がSHA-1ハッシュの場合、BINARY(20)
を介してUNHEX()
に圧縮できます。これにより、テーブルが20GB以上、現在のサイズの30%縮小されます。
sha
がSHA-1ハッシュの場合、utf8を使用しないでください。 asciiまたはlatin1を使用します。
sha
がSHA-1ハッシュであり、それがUNIQUE
インデックスを作成する列である場合は、_SHOW PROCESSLIST
_を確認します。 「key_bufferによる修復」と表示されている場合は、強制終了する必要があります。完了するまでか月かかります。 「並べ替え修理中」と表示されていれば終了する見込みです。
著者、コミッター、およびプロジェクトには、4バイトINTよりも小さいIDを使用することを検討してください。待つ!何?これらはそれぞれUNIQUE
になりますか?疑わしい。
何をSELECTs
持っていますか?それらのいくつかは「複合」インデックスを必要とするのでしょうか?
複数のALTERs
(インデックスの作成を含む)を1つのステートメントに入れます。各ALTER
は(MyISAM内の)テーブルの完全なコピーです。
_myisam_sort_buffer_size = 8G
_はRAMの半分です。これは悪いです。 3Gを提案します。
多項式
傾向は多項式に見えます。
alreadyが_UNIQUE INDEX
_と同じ列を持つテーブルの列に_PRIMARY KEY
_を追加していないことを願っています。それは完全に冗長になります。そのうちの1つに_SHOW CREATE TABLE
_を入力してください。
なぜ「多項式」なのか?もしそうなら(そして私はそのように質問します)、それは "Repair by key_buffer"の性質によるものでしょう:
各行について、すべての一意の(プライマリを含む)インデックスで列を調べ、「重複」していないことを確認します。このルックアップでは、インデックスのBTreeのブロックをフェッチして、テスト用に「key_buffer」に配置する必要があります。キーの「順序」とデータの「順序」に応じて:
891百万行はかなりです。これはMyISAMと一意のインデックスの問題です。
おそらく、この問題のない PostgreSQL に移行できますか? ghtorrentはPostgreSQLをサポートしているようです