やっと読む時間をとれた。積読が多すぎた。Rustはやっぱり難しそう。気にはなっているけれど、手を出さなくてもいいかも。特性だけわかっていればいいかな。
データ分析のためのSQL講座はよかった。WITH句があるのか、知識のアップデートができていなかったな。VIEWをつくるよりも柔軟だし良さそうだ。分析だとパフォーマンスを気にすることも、それほどないだろうし、覚えておいて損はない感じ。
Amazon: https://amzn.to/44uDLK4
やっと読む時間をとれた。積読が多すぎた。Rustはやっぱり難しそう。気にはなっているけれど、手を出さなくてもいいかも。特性だけわかっていればいいかな。
データ分析のためのSQL講座はよかった。WITH句があるのか、知識のアップデートができていなかったな。VIEWをつくるよりも柔軟だし良さそうだ。分析だとパフォーマンスを気にすることも、それほどないだろうし、覚えておいて損はない感じ。
Amazon: https://amzn.to/44uDLK4
Google Cloud SQLでMySQLのインスタンスを追加すると、タイムゾーンがUTCになる。これを、日本に変える方法のメモ。
タイムゾーンの確認のSQLと実行例。
MySQL [(none)]> SHOW VARIABLES LIKE '%time_zone%'
-> ;
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| system_time_zone | UTC |
| time_zone | SYSTEM |
+------------------+--------+
2 rows in set (0.157 sec)
MySQL [(none)]>
変更方法
1. Google Cloudの管理画面にアクセスして、SQLの管理画面を開く。
2. 設定変更するインスタンスを開く。
3. 上部メニューの「開く」をクリックする。
4. 「フラグ」のところを広げる
5. 「データベースフラグを追加」をクリックする。
6. フラグ選択で、「default_time_zone」を選択する。
7. 値に、「Asia/Tokyo」を入力する(選択ではなくて、入力する)。
8. 保存する。
9. 保存後に、インスタンスの再起動が必要になるので、再起動する。

設定変更後に確認した例。
システム側はUTCのままだが、アクセスしたとき(セッション)のタイムゾーンは、Asia/Tokyoに変わっており、現在時刻を取得した際の時間も日本時間になっていた。
MySQL [(none)]> SHOW VARIABLES LIKE '%time_zone%';
+------------------+------------+
| Variable_name | Value |
+------------------+------------+
| system_time_zone | UTC |
| time_zone | Asia/Tokyo |
+------------------+------------+
2 rows in set (0.159 sec)
MySQL [(none)]> select now();
+---------------------+
| now() |
+---------------------+
| 2023-12-11 13:50:43 |
+---------------------+
1 row in set (0.154 sec)
MySQL [(none)]>
FreeBSDで、”pkg upgrade”して、パッケージを最新の状態にしたところ、MariaDBが起動しなくなった。エラーログをみていると、DBのテーブルを修復したあとにDBがシャットダウンされている。DBのファイル破損が原因かと思い、いろいろと調べて対応したが、実はファイルの問題ではなかった。
原因は、MariaDBのバージョンが「MariaDB 10.5」に上がったことによる「my.cnf」ファイルの変更だった。
/usr/local/etc/mysql/conf.d/my.cnf
このconf.dのディレクトリに、my.cnfがあることで、これを読みにいって、その設定で失敗して、サービスが落ちていた。同じところに、client.cnfもserver.cnfもあるが、これを読まずにmy.cnfを先に読みにいって、落ちていた。my.cnfは、1つ上の階層の「/usr/local/etc/mysql/」にもあり、conf.dの下を読み込むように書かれている。
いろいろと行ったのだが、対応の正解は、conf.dの下のmy.cnfを消す(リネームでOK)。server.cnfとclient.cnfの設定を確認して、MariaDB(mysqld_safe)を起動させる。
ちなみに、errファイルに記録されていたログは下記。あとは、ログ自体が出力されていない。ログがそもそも出力されていなければ、my.cnfを疑うべきだった。
2022-02-05 15:36:39 0 [Note] /usr/local/libexec/mariadbd (initiated by: unknown): Normal shutdown
2022-02-05 15:36:39 0 [Note] Event Scheduler: Purging the queue. 0 events
2022-02-05 15:36:39 0 [Note] InnoDB: FTS optimize thread exiting.
2022-02-05 15:36:40 0 [Note] InnoDB: Starting shutdown...
2022-02-05 15:36:40 0 [Note] InnoDB: Dumping buffer pool(s) to /var/db/mysql/ib_buffer_pool
2022-02-05 15:36:40 0 [Note] InnoDB: Restricted to 2016 pages due to innodb_buf_pool_dump_pct=25
2022-02-05 15:36:40 0 [Note] InnoDB: Buffer pool(s) dump completed at 220205 15:36:40
2022-02-05 15:36:40 0 [Note] InnoDB: Removed temporary tablespace data file: "ibtmp1"
2022-02-05 15:36:40 0 [Note] InnoDB: Shutdown completed; log sequence number 1363646560; transaction id 111190553
2022-02-05 15:36:40 0 [Note] /usr/local/libexec/mariadbd: Shutdown complete
約一年ぶりに、GASと、Google CloudのCloud SQLの環境を作った。昨年はできなかったGASから、JDBCを介してのMySQL8への接続を試してみたところ、接続できることがわかった。
下図は、GASからMySQL8に接続して、バージョン情報を取得しているところ。

これでMySQLのバージョンを気にすることなく、GASから接続する環境を作れる。
毎回、検索するのも大変なので、メモ。
MySQLなどに接続するときに、Google Apps Script(GAS)からJDBCを使う。そのリファレンスのURLは下記。
ガイド
https://developers.google.com/apps-script/guides/jdbc
JDBCサービスのリファレンス
https://developers.google.com/apps-script/reference/jdbc
MySQLでSelect文の結果をファイルに書き出すのは簡単だった。Select文の最後に「INTO OUTFILE」でファイルの出力パスとファイル名を指定するだけだった。
SELECT * FROM テーブル名 INTO OUTFILE '出力ファイルパス';
それから、書き込み先の権限がないと、エラーで失敗する。その場合は、書き込みするディレクトリのパーミッションを確認する。下記は、失敗したところ。
root@localhost [zen]> select * from item into outfile '/usr/home/zen/item.csv';
ERROR 1 (HY000): Can't create/write to file '/usr/home/zen/item.csv' (Errcode: 13 "Permission denied")
root@localhost [zen]>
MySQLに登録されているユーザを調べるには、mysqlデータベースを選択して、下記のSQL文を実行する。
SELECT Host, User FROM user;
Hostが「%」のものは接続制限なし。localhostやIPアドレスが指定されているものは、そのホストからの接続のみに制限されている。
実行例)
MySQL [mysql]> use mysql;
MySQL [mysql]> SELECT Host, User FROM user;
+-----------+---------------+
| Host | User |
+-----------+---------------+
| % | testuser |
| % | root |
| % | kuro3 |
| localhost | mysql.session |
| localhost | mysql.sys |
| localhost | root |
+-----------+---------------+
6 rows in set (0.145 sec)
MySQL [mysql]>
通常は、自動コミットされるので、Update文やInsert文を実行したタイミングで、コミットされる。DBへの複数の書き込み処理を、同じタイミングで行うのは、自動コミットをオフにして、手動でコミットする必要がある。
自動コミットを無効にするには、DBコネクションの「.setAutoCommit(false)」を使用する。
手動でコミットするには、DBコネクションの「.commit()」を使用する。
試してみたところ、オートコミットをオフにした場合、「.commit()」を実行しなくても、エラーにはならない。GASのエディタ上でもアラートを上げてくれないので、注意が必要。
サンプルコード
function myFunction() {
dbConnection();
}
// --------------------------------
// SSL 接続なしで接続する
// --------------------------------
function dbConnection(){
Logger.log('start dbConnection function.');
// 接続先設定
var connectionIp = 'xxx.xxx.xxx.xxx'; // 接続のMysqlのIPアドレス(ホスト名も可)
var userName = 'user'; // 接続で使うユーザ名
var passwd = 'password'; // 接続で使うパスワード
var databaseName = 'database'; // データベース名
var addr = 'jdbc:mysql://' + connectionIp + '/' + databaseName;
Logger.log('start mysql con');
Logger.log(addr);
var connectionInfo = {
user: userName,
password: passwd
}
// DBにコネクションをはる
var connection = Jdbc.getConnection(addr, connectionInfo);
Logger.log(connection.getCatalog());
// オートコミットを無効にして、手動でコミットするようにする。
connection.setAutoCommit(false);
// sqlステートメントをデータベースに送信するためのオブジェクトを作る
var statement = connection.createStatement();
// Insert文を発行
var resultInsert = statement.executeUpdate('Insert Into List (id,listname) values ("5","kanagawa")');
// 実行結果が0なら失敗、1以上なら成功
Logger.log(resultInsert);
// 手動でコミットする。通常はオートコミットされるので必要なし。
connection.commit();
// ステートメントを閉じる
statement.close();
// コネクションを閉じる
connection.close();
}
コネクションの「.getAutoCommit()」を実行することで、DBへの書き込みがオートコミットになっているかどうかを調べることができる。
「.getAutoCommit()」の結果が、Trueならオートコミット、Falseなら手動コミット。手動コミットの場合には、「.commit()」を明示的に実行しないとDBにコミットされない。
サンプルコード
// DBにコネクションをはる
var connection = Jdbc.getConnection(addr, connectionInfo);
// オートコミットを無効にして、手動でコミットするようにする。
connection.setAutoCommit(false);
// Trueならオートコミット、Falseなら手動コミット。ログに書き出す。
Logger.log('オートコミットの設定: ' + connection.getAutoCommit());
最初に、「create user」文で、ユーザを作る。その時にパスワードも設定する。
次に、grant文で、DBの権限を割り当てる。grant文でユーザ作成も同時に行うこともできるけれど、個人的には、2文に分けた方が設定がわかりやすくて安心できる。
例)DBとユーザを作り、DBにユーザの権限を付ける。
create database dbname;
create user 'user_name'@'localhost' IDENTIFIED BY 'password';
grant all on 'dbname'.* TO 'user_name'@'localhost';