web-dev-qa-db-ja.com

存在しない場合はテーブルを作成する

私はまだデータベースを使用するのは初めてですが、現在mysqlデータベースを使用していて、bashスクリプトをいくつかの異なる環境(dev、qaなど)で使用できるため、壊れないようにしようとしています。この1行がなくても正しく動作することはわかっています。

CREATE TABLE IF NOT EXISTS backupfiles (fileName VARCHAR(20), archiveId VARCHAR(500), checkSum VARCHAR(100), glacierVault VARCHAR(100), timeStamp date);

そのテーブルが存在しないときにデータベースにその正確な行を入力すると、そのテーブルは完全に実行され、すでに存在する場合は警告が表示されますが、壊れません。

+-------+------+------------------------------------+
| Level | Code | Message                            |
+-------+------+------------------------------------+
| Note  | 1050 | Table 'backupfiles' already exists |
+-------+------+------------------------------------+

上記の行を実行し、backupfilesという名前のテーブルがない場合、それは完全に機能しますが、ハングした場合(ハングしたと言うと、そこに座って何もしない)、95%の時間と5%の時間は機能します。誰かがこのような問題に遭遇しましたか? AWS RDS(Amazon Webサービスリレーショナルデータベースサービス)を使用していますが、mysqlサーバーは5.5.27です

これが、mysqlデータベースに関連するすべてのコードです。

mysql -h portal-rds -u $user --password=$mysqlpw <<QUERY_INPUT
CREATE DATABASE IF NOT EXISTS $DATABASE;
use $DATABASE;
CREATE TABLE IF NOT EXISTS backupfiles (fileName VARCHAR(20), archiveId VARCHAR(500), checkSum VARCHAR(100), glacierVault VARCHAR(100), timeStamp date);
INSERT INTO backupfiles VALUES ('$archive_file_name', '$archiveID', '$CURRENTVAULT', '$checkSum', CURDATE());
COMMIT;
QUERY_INPUT
4
Tall Paul

2つの理由でこの問題を見つけます

理由#1

これは、MySQL 5.5.17から押しつぶされることのないバグである可能性があります。

理由#2

RDS環境でInnoDBテーブルのメタデータロックを取得しようとしていますか?痛い!

可能な回避策

RDSでのメタデータのロックを信頼する代わりに、テーブルが既に存在するかどうかをinformation_schemaに問い合わせます。テーブルがmydb.backupfilesであるとします。このクエリを実行します。

SELECT COUNT(1) FROM information_schema.tables
WHERE table_schema='mydb' AND table_name='backupfiles';

答えが0に戻ったら、CREATE TABLE backupfiles ...を実行します。それ以外の場合は、実行しないでください。

可能な解決策

最新のMySQL(5.6.12)または最新のMySQL5.5(5.5.31)にアップグレードします。うまくいけば、この問題はより新しいバージョンで解決されました

試してみる !!!

UPDATE 2013-07-11 15:16 EDT

これは、テーブルがすでに存在するかどうかを確認するためのbashコードの書き換えです

    echo "CREATE DATABASE IF NOT EXISTS $DATABASE;" > /tmp/runthis.sql
    echo "use $DATABASE;" >> /tmp/runthis.sql
    SQLSTMT="SELECT COUNT(1) FROM information_schema.tables"
    SQLSTMT="${SQLSTMT} WHERE table_schema='${DATABASE}' AND table_name='backupfiles';"
    TABLE_EXISTS=`mysql -h portal-rds -u $user --password=$mysqlpw -ANe"${SQLSTMT}"`
    if [[ ${TABLE_EXISTS} -eq 0 ]]; then
      SQLSTMT="CREATE TABLE backupfiles (fileName VARCHAR(20),"
      SQLSTMT="${SQLSTMT} archiveId VARCHAR(500), checkSum VARCHAR(100),"
      SQLSTMT="${SQLSTMT} glacierVault VARCHAR(100), timeStamp date);"
      echo "${SQLSTMT}" >> /tmp/runthis.sql
    fi
    SQLSTMT="INSERT INTO backupfiles VALUES ('$archive_file_name',"
    SQLSTMT="${SQLSTMT} '$archiveID', '$CURRENTVAULT', '$checkSum', CURDATE());"
    echo "${SQLSTMT}" >> /tmp/runthis.sql
    echo "COMMIT;" >> /tmp/runthis.sql
    mysql -h portal-rds -u $user --password=$mysqlpw < /tmp/runthis.sql
2
RolandoMySQLDBA