タグ: MySQL

  • 読了:ソフトウェアデザイン 2025年7月号

    やっと読む時間をとれた。積読が多すぎた。Rustはやっぱり難しそう。気にはなっているけれど、手を出さなくてもいいかも。特性だけわかっていればいいかな。

    データ分析のためのSQL講座はよかった。WITH句があるのか、知識のアップデートができていなかったな。VIEWをつくるよりも柔軟だし良さそうだ。分析だとパフォーマンスを気にすることも、それほどないだろうし、覚えておいて損はない感じ。

    Amazon: https://amzn.to/44uDLK4


  • Google Cloud SQLのMySQLのタイムゾーンを変更する

    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をアップデートしたらMariaDBが起動しなくなった

    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のJDBCからMySQL8に接続できるようになった

    約一年ぶりに、GASと、Google CloudのCloud SQLの環境を作った。昨年はできなかったGASから、JDBCを介してのMySQL8への接続を試してみたところ、接続できることがわかった。

    下図は、GASからMySQL8に接続して、バージョン情報を取得しているところ。

    これでMySQLのバージョンを気にすることなく、GASから接続する環境を作れる。

  • Google Apps ScriptのJDBCリファレンスのURL

    毎回、検索するのも大変なので、メモ。

    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した結果をCSVでファイル出力する

    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に登録されているユーザを調べるには、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]>
  • GASから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();
    }
  • GASのDB接続で、オートコミットになっているかを調べる

    コネクションの「.getAutoCommit()」を実行することで、DBへの書き込みがオートコミットになっているかどうかを調べることができる。

    「.getAutoCommit()」の結果が、Trueならオートコミット、Falseなら手動コミット。手動コミットの場合には、「.commit()」を明示的に実行しないとDBにコミットされない。

    サンプルコード

      // DBにコネクションをはる
      var connection = Jdbc.getConnection(addr, connectionInfo);
    
      // オートコミットを無効にして、手動でコミットするようにする。
      connection.setAutoCommit(false);
    
      // Trueならオートコミット、Falseなら手動コミット。ログに書き出す。
      Logger.log('オートコミットの設定: ' + connection.getAutoCommit());
  • MySQLでユーザを作り、DBの権限を割り当てる

    最初に、「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';
    • dbname は、データベース名を入れる
    • user_name は、ユーザ名を入れる
    • user_name は、ユーザ名を入れる