web-dev-qa-db-ja.com

MySQLテーブルファイルを分割する方法

MySQLデータベースにinnodb_file_per_tableが有効になっているテーブルがあります。私のテーブルの1つは約20GBで、大きくなっています。テーブルを個別のファイルに分割するにはどうすればよいですか?

tab1に保存されている/var/lib/mysql/db_name/tab1.frmという名前のテーブルがあり、サイズが約20GBであるとします。そのテーブルを2つのファイルtab1-1.frmtab1-2.frmに分割して、それぞれ10 GBのサイズにしたいと思います。

テーブル定義:

CREATE TABLE cdr (
     gid bigint(20) NOT NULL AUTO_INCREMENT,
     id bigint(20) NOT NULL,
     start datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
     clid varchar(80) NOT NULL DEFAULT '',
     src varchar(80) NOT NULL DEFAULT '',
     channel varchar(80) NOT NULL DEFAULT '',
     duration int(11) NOT NULL DEFAULT '0',
     uniqueid varchar(32) NOT NULL DEFAULT '',
     dnid varchar(20) NOT NULL DEFAULT '',
     service varchar(100) NOT NULL DEFAULT '',
     cost int(11) NOT NULL DEFAULT '0',
     PRIMARY KEY (gid),
     UNIQUE KEY id (id,prefix),
     KEY start (start),
     KEY clid (clid),
     KEY service (service)
) ENGINE=InnoDB AUTO_INCREMENT=37024605 DEFAULT CHARSET=latin1
1
shgnInc

_.ibd_ではなく、20 GBの_.frm_ファイルであると思いますか?

2つの物理的に分離したテーブルが必要な場合は、tab1-1をtab1-2にコピーして(2つのコピーを作成する)、それぞれからデータの半分を削除します。それでも、後で両方のテーブルをOptimize縮小する必要があります。

MySQLパーティションオプションを使用すると、ある範囲(たとえば、すべてのIDがパーティション1で10000未満、パーティション1で10001-20000など)でパーティション分割する1つのテーブル_tab1_があります。これは、ファイルシステム上に2つ(またはそれ以上)の個別のファイル(_tab1.frm_および_tab1#p#partition1.ibd_、_tab1#p#partition2.ibd_などのさまざまなファイル)として表示されます。ただし、ファイルサイズを制御することはできません。

上記の例で、すべてのIDがたとえば10000未満の場合、ファイルサイズに違いはありません。

テーブルの構造とmysqlのバージョンを提供すると役立ちます。

更新:2015-04-13 11:44(GMT + 1):

テーブル構造を見ると、最初に目にするのは、_Primary key_と_Unique Key_があるために問題が発生することです。

分割テーブルの分割式で使用されるすべての列は、テーブルが持つ可能性のあるすべての一意のキーの一部である必要があります。

つまり、テーブルのすべての一意のキーは、テーブルのパーティション式のすべての列を使用する必要があります。 (これは定義により一意のキーであるため、これにはテーブルの主キーも含まれます。

http://dev.mysql.com/doc/refman/5.6/en/partitioning-limitations-partitioning-keys-unique-keys.html

現在、パーティショニングを試行するとエラーが発生します。

例えば.

_Error Code: 1503. A PRIMARY KEY must include all columns in the table's partitioning function_

または

_Error Code: 1503. A UNIQUE INDEX must include all columns in the table's partitioning function_

最初に以下のいくつかを確認することをお勧めします。

また、ライブデータベースでは実行したくないパーティションの構築にかなり時間がかかる可能性があるため、非ライブサーバーでこれをテストしてください。

更新:2015-04-27 09:52(GMT + 1):

いくつか決断を迫られているようです。 。 。

Start列を使用するには、startを主キー(PK)と一意キーの両方に追加する必要があります。

_    ALTER TABLE `test`.`cdr` 
    DROP PRIMARY KEY
    ,DROP INDEX `id`
    ,ADD PRIMARY KEY (`gid`,`start`)
    ,ADD UNIQUE INDEX `id` (`id` ASC, `prefix` ASC, `start` ASC);
_

PKへの影響はごくわずかです(直接書き込みを行わない限り、自動インクリメントのポイントが無効になります)。

ただし、これは_id,prefix,start_全体でのみ一意になるため、一意キーに問題を引き起こす可能性があります。

例えばinsert into test.cdr (id,prefix,start) values (100,'abc','2015-04-27 09:19:00'),(100,'abc','2015-04-27 09:19:01');

以前は重複キーエラーが発生していましたが、有効になります。

したがって、その一意性がいかに重要であるかを考慮する必要があります。

IS非常に重要な場合は、代わりにidによるパーティショニングを検討することをお勧めしますが、それはデータがどのように簡単であるか(および_id,prefix_をPKとして使用し、gidを標準(一意ではない)keyに変換します。

それがそれほど重要でない場合は、一意キーを標準キーに変換し、_gid,start_をPKにすることができます。

2
IGGt

PKに日付を追加し、一意のキーをキーに置き換えることができます。次に、アプリケーションで一意のチェックを処理する必要があります。

別の解決策は、たとえば最初から派生した年列を追加してから、年をPKと一意のキーに追加することです。次に、年ごとに分割するように機能するはずです。

1
Jonas