コピペコードで快適生活

明日使えるソースを自分のために

シェルスクリプトで対話的に選択肢を選ばせる

よく忘れるのでメモしておく。

#
# 入力値チェック/セット
#
echo 'CloudFrontログを抽出します。'
echo '対象ドメインを番号で指定してください'
echo '
1) a.example.com
2) b.example.com
3) c.example.com
'
read num
case ${num} in
  1)
    DOMAIN='a.example.com'
    CF_ID='xxxxx'
    ;;
  2)
    DOMAIN='b.example.com'
    CF_ID='xxxxx'
    ;;
  3)
    DOMAIN='c.example.com'
    CF_ID='xxxxx'
    ;;
  *)
    echo '番号が不正です'
    exit
    ;;
esac

PostgreSQLでプロセスとロック状況を確認する

## 実行中のSQLを確認する。
SELECT * FROM pg_stat_activity;

## 実行中のSQLを確認する
## スロークエリとか主に見る分だけ
SELECT pid, query_start, substr(query, 0, 80) AS query FROM pg_stat_activity WHERE state='active' ORDER BY query_start;

## ロック状況の確認
SELECT l.pid, db.datname, c.relname, l.locktype, l.mode
FROM pg_locks l
LEFT JOIN pg_class c ON l.relation=c.relfilenode
LEFT JOIN pg_database db ON l.database = db.oid
ORDER BY l.pid;

## AccessExclusiveLockロックがかかっているか
SELECT l.pid, db.datname, c.relname, l.locktype, l.mode
FROM pg_locks l
LEFT JOIN pg_class c ON l.relation=c.relfilenode
LEFT JOIN pg_database db ON l.database = db.oid
WHERE l.mode = 'AccessExclusiveLock'
ORDER BY l.pid;

## Railsのマイグレーションでロックをかけない呪文
## デフォだとSELECTも通さないAccessExclusiveLockがかかる
class AddStatusToUsers < ActiveRecord::Migration
  disable_ddl_transaction!

  def up
    # 略
    Users.find_each do |user|
      user.update_columns(status: 'xxx')
    end
  end

  def down
    # 略
  end
end

## インデックス追加中にロックかけない
## (concurrentlyオプションを有効にする)
## https://thoughtbot.com/blog/how-to-create-postgres-indexes-concurrently-in
class AddIndexToAsksActive < ActiveRecord::Migration
  disable_ddl_transaction!

  def change
    add_index :asks, :active, algorithm: :concurrently
  end
end

メモ

PostgreSQL×Rails環境でのマイグレーションで、バカでかいテーブルに対して、add_column + eachまわしてupdate ということをやると、こうなる。

・add_columnsで、AccessExclusiveLockかかる。
・AccessExclusiveLockの中でeachでUPDATE走る。
・AccessExclusiveLockはSELECTも通さないロックなので、
 該当テーブルに対するSELECTがすべて待ちになる。
・待ちのSELECTでDBプロセス食い尽くす。
・DBが応答なくなる。
・障害発生 :unko:

Imagemagickコマンドメモ

## 黒塗り / 中央寄せ / リサイズせず正方形に整える
convert -background black -gravity center -extent 960x960 tamanegi.png _tamanegi.png

## 白色を透過に変える(transparent) / 白から5%くらいずれていても透過させる(fuzz)
convert input.png -fuzz 5% -transparent white output.png

## 複数の画像をマージする。
## 横につなげる
convert -append 01.png 02.png out.png

## 縦につなげる
convert +append 01.png 02.png out.png

## 横につなげる + 上下左右に30の余白を開けて連結する
convert -append -border 30x30 01.png 02.png out.png

## 文字画像を作る
convert -size "256x128" -background "#f5f5f5" -fill "#dc143c" caption:"image\nmagick\n" output.png

sidekiqをGracefulShutdownする

# >= 5.0.0
kill -TSTP [worker_pid]

# < 5.0.0
kill -USR1 [worker_pid]

# すると、
# 該当のworkerにキューが入らなくなる。
# psコマンドでみたときに stopping がつく。
sidekiq 4.2.10 app_name [0 of 8 busy] stopping

# busyが0になったら、-TERM送って終了
kill -TERM [worker_pid]

sidekiq を安全に止める - Qiita より

goenv環境でdepを使うメモ

QuickStart

まずはこれでgoenvをインストールする。
http://kinosuke.hatenablog.jp/entry/2019/04/11/104837

# depのインストール
# ※GOPATH以下にインストールされる
go get -u github.com/golang/dep/cmd/dep

# goenv環境でやるとdepコマンドのパスが通らないので、とりあえずパス指定で実行する。
# パスを通してもいいけど、goのバージョン切り替えるたびにパス変えるのめんどくさいかも。

# 現在の構成を解析して Gopkg.toml、Gopkg.lock を生成
"${GOPATH}/bin/dep" init

# パッケージをvendorディレクトリ以下にインストール
"${GOPATH}/bin/dep" ensure

# 新しいパッケージを追加
"${GOPATH}/bin/dep" ensure -add github/gin-gonic/gin

# パッケージをアップデート
"${GOPATH}/bin/dep" ensure -update github/gin-gonic/gin

# 現在の状態を出力する
"${GOPATH}/bin/dep" status

参考
Goオフィシャルチーム作成の依存関係管理ツール dep を試してみた | DevelopersIO

RspecでSQLやRailsのログを出力したい

こんな感じで

# spec/rails_helper.rb

# 略

Rails.logger = Logger.new(STDOUT) # Rails.loggerを出す
ActiveRecord::Base.logger = Logger.new(STDOUT) # SQLログ出す

RSpec.configure do |config|
  # 略
end

※STDOUTは組み込み変数

STDOUT.puts "hogehoge"

のようにすれば標準出力される。

GoModulesを使ってパッケージ管理する

QuickStartメモ

# プロジェクトディレクトリを掘る
mkdir -p github.com/kinosuke01/gin-tutorial
cd github.com/kinosuke01/gin-tutorial/

# 初期化する → go.modというパッケージリストを保持するファイルができる
go mod init github.com/kinosuke01/gin-tutorial/
go: creating new go.mod: module github.com/kinosuke01/gin-tutorial/

# main.go書いてみる
cat main.go
=====
package main

import (
    "fmt"
    "github.com/gin-gonic/gin"
)

func main() {
    fmt.Println("hello!!!")

    r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })
    r.Run() // listen and serve on 0.0.0.0:8080
}
=====

# ビルドする
# 必要なパッケージが ${GOPATH}/pkg/* 以下に自動でインストールされてbuildされる。
# パッケージリストが go.mod に追記される
go build main.go

# 実行ファイルを実行する
./main
hello!!!
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /ping                     --> main.main.func1 (3 handlers)
[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on :8080

参考にさせていただきました。 https://qiita.com/propella/items/e49bccc88f3cc2407745