- 投稿日:2022-02-01T21:49:48+09:00
レプリケーション遅延について調べてみた
レプリケーションとは DBサーバーのレプリカ(複製)を、複数持つことができる機能 マスタースレーブ構成とは 主となるDBサーバーをマスター(サーバー)、レプリカをスレーブ(サーバー)という。 マスターとスレーブのセットを、マスタースレーブ構成という。 基本的には、リアルタイムでマスターとスレーブは同期されている マスターとスレーブは 1:N の関係にある。 メリット マスターに障害が起きた時、スレーブを使うことができる。 --> システムを止めることなく、高い可用性を実現することができる。 デメリット DBサーバーを複数置くことになるので、DBサーバー台数分の料金がかかる。 常にマスターとスレーブは同期しているので、マスターに何か問題があると、その状態もスレーブに複製されてしまう レプリケーション遅延とは レプリケーション遅延とは、マスターの状態をスレーブに同期するまでの時間が遅延してしまうこと。 例えば、レプリケーション遅延している時にマスターサーバーがダウンした際、マスターとスレーブの整合が取れなくなってしまう恐れがある。 レプリケーション遅延回避策 巨大なSQLを流さないこと 大量データを更新する場合は、N件ずつ分けて更新するようにする RDSやCloudSqlを使っている場合は、コンソールで負荷をみながら進めること
- 投稿日:2022-02-01T21:48:18+09:00
Mysql2::Error: Duplicate entry 'xxx' for key 'PRIMARY' エラー解決方法
エラーの概要 Mysql2::Error: Duplicate entry '100018' for key 'PRIMARY'と表示され、レコードを追加することができず、、 エラーメッセージから主キーが重複しているということは理解できたが、該当の主キーとは何なのか、、 そんな中、無事解決できたので備忘録としてまとめておきます。 結論から、AUTO_INCREMENT属性を該当テーブルのidに設定していたため、レコード作成時にMySQLが自動的にid番号を割り当てていたことによる重複が原因でした。 実装箇所をテストしていた際に、誤って操作したことによるものだと思われます、、反省。 前提 OS:MAC DB:MySQL TablePlusを使用してDBデータを確認しています。 1.AUTO_INCREMENTの値を確認する 取得する該当テーブルを指定してテーブルデータを確認してみました。 TablePlusの操作 左上のSQLをクリック コマンドを入力し、⌘ + Enterで実行 -- 構文 SHOW TABLE STATUS LIKE ('テーブル名'); -- 出力コマンド SHOW TABLE STATUS LIKE ('orders'); => 100017 出力結果からAUTO_INCREMENTの値が100017であることが確認できました。 2.最大値のレコードを取得 今回の場合、PRIMARYキーのidカラムの重複が原因のため、該当カラムの最大値レコード数を取得してみました。 SELECT MAX(id) FROM orders; => 100133 出力結果からテーブルに存在する1番最後のレコードのidが100133であることが確認できました。 本来なら、次に作成されるレコードのidには100134が付与されるのだが、どういうことかidに100018が付与されてしまい、「 重複してるー 」とエラーメッセージが表示されていたんですね、、 3.次回レコード作成時のAUTO_INCREMENTの値を確認 TablePlusで確認することができます。 TablePlusの操作 左上のitemsをクリックし、該当テーブルを選択する。 画面下にあるStructureをクリックする。 表示されたinfoをクリックし、1番下までスクロールすると確認できます。 ENGINE=InnoDB AUTO_INCREMENT=100018 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='xxx'; 確認したところ、100018と表示されており、本来は100134である必要があります。 4.AUTO_INCREMENTの値を変更 最後に、正しい値をALTER文で変更していきます。 ALTER TABLE orders AUTO_INCREMENT = 100134; 出力後 ENGINE=InnoDB AUTO_INCREMENT=100134 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='xxx'; 先ほど TablePlus で確認したAUTO_INCREMENTの値が反映されていることが分かります。 その結果、無事新規レコードを作成することに成功! 最後に 解決できたときの達成感って格別ですよね笑 SHOW TABLE STATUS で 取得できるデータ 【ストレージエンジンがInnoDBの場合】 項目 情報 Name テーブル名 Engine テーブルのストレージエンジン名 Version テーブルの .frm file. のバージョン番号 Row_format レコードの保存形式 Rows レコードの行数 Avg_row_length レコードの平均行長 Data_length クラスタ化されたインデックスに割り当てられるおおよその容量 (バイト単位) Max_data_length 未使用 Index_length クラスタ化されていないインデックスに割り当てられる領域の概算量 (バイト単位) Data_free 割り当てられているが、使用されていないバイト数 Auto_increment 次のAUTO_INCREMENT値 Create_time テーブル作成時刻 Update_time データファイルの最新更新時刻 Check_time 最後にチェックされた時刻 Collation テーブルのデフォルトの照合 Checksum ライブチェックサム値 Create_options パーティションテーブルの partitioned が表示(CREATE TABLE で使用される追加のオプション) Comment テーブルを作成時に使用されたコメント
- 投稿日:2022-02-01T14:36:00+09:00
formを用いたHTMLからMySQLへの値の挿入方法について。
formを用いたHTMLからMySQLへの値の挿入方法 Node.jsとMySQLを用いたアプリの開発途中に少し詰まったので備忘録として書いておきます。 HTML.CSS <form action="new" method="post"> <p>名前</p> <input type="text" name="name" > <p>性別</p> <input type="text" name="gender"> <p>年齢</p> <input type="text" name="age" > <p>生年月日</p> <input type="date" name="dob"> <input href="/new" type="submit" value="送信する"> </form> 例えば、このようなformの内容をMySQLに挿入したい場合、Node.js上でこのように記述することで挿入が可能です。 Node.js //データの追加はpost送信を用いる app.post('/new', (req, res) => { console.log(req.body); //formからの内容はreq.bodyに格納されるため、その中からformの内容を取り出し変数に挿入する処理。 const name = req.body.name; const gender = req.body.gender; const age = req.body.age; const dob = req.body.dob; console.log(name, gender, age, dob); //MySQLへ接続し、値を挿入する処理 connection.query( //変数を挿入したい部分は"?"で記述する。 'INSERT INTO users (name, gender, age, dob, level) VALUES (?, ?, ?, ?, ?)', //[]で囲んだ中に"?"に対応する変数を記述する。 [name, gender, age, dob], (error, results) => { console.log(results) console.log(error) res.redirect('/top',); } ); });
- 投稿日:2022-02-01T13:33:07+09:00
Kubernetes内のPodsからMySQLサーバに接続する方法
Podsを起動する kubectl run mysql-client --image=mysql:5.7 \ -it --rm \ --restart=Never -- /bin/bash MySQLサーバに接続する mysql -h mysql-service -uroot -proot_password mysql
- 投稿日:2022-02-01T04:26:45+09:00
[laravel]php artisan migrate が通らないときの解決例
エラー内容 $ php artisan migrate Migrating: 2022_01_29_163203_create_projects_table Illuminate\Database\QueryException SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'projects' already exists (SQL: create table `projects` (`id` bigint unsigned not null auto_increment primary key) default character set utf8mb4 collate 'utf8mb4_unicode_ci') at vendor/laravel/framework/src/Illuminate/Database/Connection.php:712 708▕ // If an exception occurs when attempting to run a query, we'll format the error 709▕ // message to include the bindings with SQL, which will make this exception a 710▕ // lot more helpful to the developer instead of just the database's errors. 711▕ catch (Exception $e) { ➜ 712▕ throw new QueryException( 713▕ $query, $this->prepareBindings($bindings), $e 714▕ ); 715▕ } 716▕ } +9 vendor frames 10 database/migrations/2022_01_29_163203_create_projects_table.php:32 Illuminate\Support\Facades\Facade::__callStatic("create") +21 vendor frames 32 artisan:37 Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) まず結論(解決方法) mysqlに既に他のlaravelプロジェクトでテーブル出来上がっているため、そのテーブルを消すことでmigrateが通るようになります。 なぜ記事を書いたのか 久しぶりにdockerを使わないでlaravelの環境構築したところ、みたことのない種類のエラーに出会い躓きました。 そのためぱっと見どこにエラー文が書いてあるかわからず、解決まで時間がかかったので備忘録の意味も含めて記載しようと思いました。 エラー文はどこにあるのか 筆者は最初は ➜ 712▕ throw new QueryException( を見て、その文字で検索して結局解決できず、試行錯誤して偶然解決までたどり着きました。 解決後にエラーをよくよくみたところ SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'projects' already exists ~ というエラー文があり、「既にテーブルが入っている」と言っていたことに気づきました。 結論ですが、エラー文はSQLSTATE[42S01]:~ の部分に書いてあります。 まとめ 今回の記事でお伝えしたかったことは下記の2点です。 エラー解決の具体例を探している場合:DBに他のプロジェクトのテーブルが入っていないか確認する エラー文が何を言っているかわからず困っている場合:SQLSTATE[42S01]:~の部分を読んでみる