# my opinion is my own > memo blog author: zatoima url: https://zatoima.github.io/ ## Blog Posts (Full Content) --- ### Hugo製ブログにMCP Serverとllms.txtを実装する date: 2026-02-23 url: https://zatoima.github.io/hugo-blog-mcp-server-llms-txt/ tags: Hugo, Claude Code はじめに 自分のHugoブログ(GitHub Pages)に対して、以下2つのアプローチでAI/LLM向けのインターフェースを実装した。 MCP Server - Claude Codeから記事の検索・閲覧ができるMCPサーバー(リポジトリのクローン不要、HTTPフェッチ方式) llms.txt - Webサイト上でLLM向けにコンテンツを公開する標準フォーマット MCP(Model Context Protocol)とは MCPはAnthropicが提唱するプロトコルで、AIモデルが外部のデータソースやツールと連携するための標準的な仕組みである。MCP Serverを作ることで、Claude CodeなどのAIツールからブログの記事検索・閲覧が可能になる。 MCP Serverの実装 データ取得方式 当初はリポジトリをクローンしてローカルのMarkdownファイルを直接読む方式だったが、利用者にクローンを強いるのは不便なため、サイトが公開しているllms-full.txtをHTTPで取得する方式に変更した。 ┌──────────────┐ HTTP GET ┌──────────────────────┐ │ MCP Server │ ───────────────── │ zatoima.github.io │ │ (Node.js) │ /llms-full.txt │ (GitHub Pages) │ └──────────────┘ └──────────────────────┘ │ │ stdio ▼ ┌──────────────┐ │ Claude Code │ └──────────────┘ これにより、リポジトリのクローンは不要になった。MCP Serverのソースコードだけ取得してビルドすればよい。データは10分間キャッシュされ、キャッシュ期限後は自動で再取得される。 構成 mcp-server/ ├── package.json ├── tsconfig.json ├── src/ │ └── index.ts └── dist/ └── index.js 依存ライブラリは @modelcontextprotocol/sdk のみ。Node.js標準のfetchでllms-full.txtを取得し、テキストパースで記事データを抽出する。 提供ツール MCP Serverでは5つのツールを実装した。 ツール名 説明 search_posts キーワードでタイトル・本文・タグを全文検索 read_post slugまたはタイトルの一部から記事全文を取得 list_posts 記事一覧の取得(タグ・カテゴリ・年でフィルタ可) list_tags 全タグと記事数の一覧 blog_stats ブログの統計情報(記事数、年別投稿数、人気タグ) 実装のポイント llms-full.txtは---で区切られた記事の連続テキストであるため、これをパースして構造化データに変換する。 import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; const SITE_URL = "https://zatoima.github.io"; // llms-full.txtからデータを取得・パース async function getPosts(): Promise<BlogPost[]> { const res = await fetch(`${SITE_URL}/llms-full.txt`); const text = await res.text(); return parseLlmsFullTxt(text); // テキストを記事データに変換 } // ツール登録の例: 記事検索 server.tool( "search_posts", "ブログ記事をキーワードで検索する", { query: z.string().describe("検索キーワード"), limit: z.number().optional().default(10), }, async ({ query, limit }) => { const posts = await getPosts(); const q = query.toLowerCase(); const results = posts .filter( (p) => p.title.toLowerCase().includes(q) || p.content.toLowerCase().includes(q) || p.tags.some((t) => t.toLowerCase().includes(q)) ) .slice(0, limit); // ... 結果を返す } ); セットアップ リポジトリ全体のクローンは不要。MCP Serverのソースコードだけ取得してビルドする。 # MCP Serverのソースを取得してビルド git clone --depth 1 --filter=blob:none --sparse https://github.com/zatoima/zatoima.github.io.git cd zatoima.github.io && git sparse-checkout set mcp-server cd mcp-server && npm install && npx tsc # Claude Codeに登録 claude mcp add zatoima-blog node $(pwd)/dist/index.js 登録後、Claude Codeのセッション内で以下のように使用できる。 # 記事検索 mcp__zatoima-blog__search_posts(query="Aurora") # 統計情報 mcp__zatoima-blog__blog_stats() llms.txtの実装 llms.txtとは llms.txtはWebサイトの内容をLLMに理解させるためのフォーマットである。robots.txtのAI版のようなもので、サイトの概要と記事一覧をプレーンテキストで提供する。 /llms.txt - 記事タイトル・URL・タグの一覧(軽量版) /llms-full.txt - 全記事の本文を含む完全版 Hugoでの生成方法 1. hugo.tomlにカスタム出力フォーマットを定義 [mediaTypes] [mediaTypes."text/llms"] suffixes = ["txt"] [mediaTypes."text/llms-full"] suffixes = ["txt"] [outputFormats] [outputFormats.llms] mediaType = "text/llms" baseName = "llms" isPlainText = true notAlternative = true [outputFormats.llms-full] mediaType = "text/llms-full" baseName = "llms-full" isPlainText = true notAlternative = true [outputs] home = ["HTML", "RSS", "JSON", "llms", "llms-full"] 2. テンプレートファイルの作成 layouts/_default/index.llms.txt(軽量版): # {{ .Site.Title }} > {{ .Site.Params.description }} author: zatoima url: {{ .Site.BaseURL }} ## Blog Posts {{- $pages := where .Site.RegularPages "Section" "blog" }} {{ range $pages }} - [{{ .Title }}]({{ .Permalink }}) ({{ .Date.Format "2006-01-02" }}){{ with .Params.tags }} [{{ delimit . ", " }}]{{ end }} {{- end }} layouts/_default/index.llms-full.txt(完全版): {{- $pages := where .Site.RegularPages "Section" "blog" }} {{ range $pages }} --- ### {{ .Title }} date: {{ .Date.Format "2006-01-02" }} url: {{ .Permalink }} {{ .Plain }} {{ end }} 3. HTMLヘッダーへのリンク追加 layouts/_default/baseof.htmlの<head>内に以下を追加する。 <link rel="alternate" type="text/plain" href="/llms.txt" title="LLMs.txt" /> <link rel="alternate" type="text/plain" href="/llms-full.txt" title="LLMs-full.txt" /> ナビゲーションにもリンクを追加した。 <a href="/llms.txt" title="LLMs.txt - AI/LLM向けサイト情報">llms.txt</a> 生成結果 ファイル 行数 内容 llms.txt 414行 記事タイトル・URL・タグの一覧 llms-full.txt 7,448行 全記事の本文を含む完全版 コンテキストウィンドウへの影響 MCP Serverはllms-full.txt(約1.8MB / 推定50万トークン)を起動時にHTTPで取得しメモリ上に保持する。しかし、この全データがClaude Codeのコンテキストウィンドウに流れるわけではない。 各ツールがClaude Codeに返すデータ量は以下の通り。 ツール 返すデータ コンテキスト消費 search_posts タイトル一覧のみ 小 list_posts タイトル一覧のみ 小 list_tags タグと件数の集計 小 blog_stats 統計サマリ 小 read_post 1記事の全文 記事による(大) read_post以外のツールは検索・集計結果のサマリのみを返すため、コンテキストウィンドウへの影響は小さい。1.8MBの全記事データはMCP Serverプロセスのメモリに留まり、Claude Codeには流れない。read_postだけは記事全文を返すため、長い記事の場合はコンテキストを圧迫する可能性がある。 まとめ Hugo製の静的ブログに対して、2つの異なるアプローチでAI/LLMとの連携を実装した。 方式 用途 動作環境 クローン MCP Server Claude Codeからの記事操作 ローカル(Node.js) 不要(HTTPフェッチ) llms.txt Web上でのLLM向けコンテンツ公開 GitHub Pages(静的ファイル) 不要 MCP Serverはllms-full.txtをHTTPで取得する方式にしたことで、リポジトリのクローンが不要になった。llms.txtがMCP Serverのデータソースを兼ねる構成になっており、Hugoビルド時に記事データが自動更新される。静的サイトでも工夫次第でAIフレンドリーな対応が可能である。 参考資料 Model Context Protocol llms.txt proposal Hugo Custom Output Formats --- ### LLM論文サーベイ(2026-02-23) date: 2026-02-23 url: https://zatoima.github.io/llm-papers-2026-02-23/ tags: LLM, AI, 論文 はじめに 本記事は2026-02-23時点でのLLM関連の注目論文をまとめたものです。arXiv、Semantic Scholar、Hugging Face Daily Papersから自動収集し、Claude APIで日本語要約を生成しています。 1. VIRAASAT: Traversing Novel Paths for Indian Cultural Reasoning 著者: Harshul Raj Surana, Arijit Maji, Aryan Vats, Akash Ghosh, Sriparna Saha ほか 公開日: 2026-02-20 ソース: arxiv arXiv ID: 2602.18429v1 要約 VIRAASATは、インド文化に関する多段階推論(マルチホップQA)データセットを半自動的に生成する新しいアプローチである。700以上の専門家が精選した文化的アーティファクトからなる知識グラフを活用し、インドの全28州・8連邦直轄領にわたる13の文化属性(歴史、祭りなど)をカバーする3,200以上のマルチホップ質問を生成した。最先端LLMの評価により、Chain-of-Thought(CoT)によるファインチューニングでは低頻度の文化的事実の統合・根拠付けに限界があることが判明した。この課題を解決するため、知識グラフ上の原子的操作を内部的にシミュレートするSymbolic Chain-of-Manipulation(SCoM)フレームワークを提案し、教師ありファインチューニングにおいて標準CoTベースラインを最大20%上回る性能を達成した。 原文Abstract Large Language Models (LLMs) have made significant progress in reasoning tasks across various domains such as mathematics and coding. However, their performance deteriorates in tasks requiring rich socio-cultural knowledge and diverse local contexts, particularly those involving Indian Culture. Existing Cultural benchmarks are (i) Manually crafted, (ii) contain single-hop questions testing factual recall, and (iii) prohibitively costly to scale, leaving this deficiency largely unmeasured. To address this, we introduce VIRAASAT, a novel, semi-automated multi-hop approach for generating cultural specific multi-hop Question-Answering dataset for Indian culture. VIRAASAT leverages a Knowledge Graph comprising more than 700 expert-curated cultural artifacts, covering 13 key attributes of Indian culture (history, festivals, etc). VIRAASAT spans all 28 states and 8 Union Territories, yielding more than 3,200 multi-hop questions that necessitate chained cultural reasoning. We evaluate current State-of-the-Art (SOTA) LLMs on VIRAASAT and identify key limitations in reasoning wherein fine-tuning on Chain-of-Thought(CoT) traces fails to ground and synthesize low-probability facts. To bridge this gap, we propose a novel framework named Symbolic Chain-of-Manipulation (SCoM). Adapting the Chain-of-Manipulation paradigm, we train the model to simulate atomic Knowledge Graph manipulations internally. SCoM teaches the model to reliably traverse the topological structure of the graph. Experiments on Supervised Fine-Tuning (SFT) demonstrate that SCoM outperforms standard CoT baselines by up to 20%. We release the VIRAASAT dataset along with our findings, laying a strong foundation towards building Culturally Aware Reasoning Models. 2. SPQ: An Ensemble Technique for Large Language Model Compression 著者: Jiamin Yao, Eren Gultepe 公開日: 2026-02-20 ソース: arxiv arXiv ID: 2602.18420v1 要約 本研究は、大規模言語モデル(LLM)の圧縮手法として、分散保持型特異値分解(SVD)、活性化ベースの枝刈り(Pruning)、学習後線形量子化(Quantization)を組み合わせたアンサンブル技術SPQを提案する。各手法はMLPの冗長ニューロン除去、アテンション射影の低ランク分解、全線形層の8ビット量子化というそれぞれ異なる非効率性を対象とし、同一圧縮率において単独手法よりも優れたパープレキシティを達成する。LLaMA-2-7Bへの適用では、最大75%のメモリ削減を実現しつつ、WikiText-2のパープレキシティを5.47から4.91に改善し、C4・TruthfulQA・GSM8Kなどの下流タスクでも精度を維持した。GPTQやSparseGPTといった強力なベースラインと比較しても、SPQはより少ないメモリ使用量(GPTQの7.16GBに対し6.86GB)で競争力のある性能を示し、推論スループットでは最大1.9倍の高速化を達成しており、メモリ制約環境でのLLM実用展開に有効な手法である。 原文Abstract This study presents an ensemble technique, SPQ (SVD-Pruning-Quantization), for large language model (LLM) compression that combines variance-retained singular value decomposition (SVD), activation-based pruning, and post-training linear quantization. Each component targets a different source of inefficiency: i) pruning removes redundant neurons in MLP layers, ii) SVD reduces attention projections into compact low-rank factors, iii) and 8-bit quantization uniformly compresses all linear layers. At matched compression ratios, SPQ outperforms individual methods (SVD-only, pruning-only, or quantization-only) in perplexity, demonstrating the benefit of combining complementary techniques. Applied to LLaMA-2-7B, SPQ achieves up to 75% memory reduction while maintaining or improving perplexity (e.g., WikiText-2 5.47 to 4.91) and preserving accuracy on downstream benchmarks such as C4, TruthfulQA, and GSM8K. Compared to strong baselines like GPTQ and SparseGPT, SPQ offers competitive perplexity and accuracy while using less memory (6.86 GB vs. 7.16 GB for GPTQ). Moreover, SPQ improves inference throughput over GPTQ, achieving up to a 1.9x speedup, which further enhances its practicality for real-world deployment. The effectiveness of SPQ’s robust compression through layer-aware and complementary compression techniques may provide practical deployment of LLMs in memory-constrained environments. Code is available at: https://github.com/JiaminYao/SPQ_LLM_Compression/ 3. Subgroups of $U(d)$ Induce Natural RNN and Transformer Architectures 著者: Joshua Nunley 公開日: 2026-02-20 ソース: arxiv arXiv ID: 2602.18417v1 要約 本論文は、U(d)の閉部分群上に隠れ状態を持つ系列モデルの直接的な枠組みを提示する。最小限の公理的設定から出発し、部分群の選択が状態空間・接線射影・更新写像のドロップイン置換として機能する共通の骨格から、リカレント型およびTransformer型のテンプレートを導出する。O(d)に特殊化した直交状態RNNおよびTransformerモデルを、Tiny ShakespeareとPenn Treebankにおいてパラメータ数を揃えた条件で評価している。さらに、接線空間における一般的な線形混合拡張を報告しており、これは部分群の選択に依存せず適用可能であり、現行のO(d)実験において有限パラメータ予算下での性能向上を実現している。 原文Abstract This paper presents a direct framework for sequence models with hidden states on closed subgroups of U(d). We use a minimal axiomatic setup and derive recurrent and transformer templates from a shared skeleton in which subgroup choice acts as a drop-in replacement for state space, tangent projection, and update map. We then specialize to O(d) and evaluate orthogonal-state RNN and transformer models on Tiny Shakespeare and Penn Treebank under parameter-matched settings. We also report a general linear-mixing extension in tangent space, which applies across subgroup choices and improves finite-budget performance in the current O(d) experiments. 4. “How Do I …?”: Procedural Questions Predominate Student-LLM Chatbot Conversations 著者: Alexandra Neagu, Marcus Messer, Peter Johnson, Rhodri Nelson 公開日: 2026-02-20 ソース: arxiv arXiv ID: 2602.18372v1 要約 本研究は、大規模言語モデル(LLM)ベースの教育用チャットボットに対する学生の質問パターンを、形成的自主学習と総括的評価課題という2つの学習文脈から分析したものである。6,113件のメッセージを11種のLLMと3名の人間評価者により、4つの既存分類スキーマを用いて分類した結果、LLMによる評価者間信頼性は中程度から良好であり、人間評価者よりも一貫性が高いことが示された。両学習文脈において「手続き的(procedural)」質問が最も多く、特に総括的評価の準備時にその傾向が顕著であった。一方で、既存の分類スキーマは複合的なプロンプトの意味的豊かさに対応しきれず、チャットボット統合のリスクと利点の理解には限界があることも明らかになった。今後は、談話心理学における会話分析手法などを適用し、複数ターンにわたる会話の微妙なニュアンスを捉えるアプローチが推奨されている。 原文Abstract Providing scaffolding through educational chatbots built on Large Language Models (LLM) has potential risks and benefits that remain an open area of research. When students navigate impasses, they ask for help by formulating impasse-driven questions. Within interactions with LLM chatbots, such questions shape the user prompts and drive the pedagogical effectiveness of the chatbot’s response. This paper focuses on such student questions from two datasets of distinct learning contexts: formative self-study, and summative assessed coursework. We analysed 6,113 messages from both learning contexts, using 11 different LLMs and three human raters to classify student questions using four existing schemas. On the feasibility of using LLMs as raters, results showed moderate-to-good inter-rater reliability, with higher consistency than human raters. The data showed that ‘procedural’ questions predominated in both learning contexts, but more so when students prepare for summative assessment. These results provide a basis on which to use LLMs for classification of student questions. However, we identify clear limitations in both the ability to classify with schemas and the value of doing so: schemas are limited and thus struggle to accommodate the semantic richness of composite prompts, offering only partial understanding the wider risks and benefits of chatbot integration. In the future, we recommend an analysis approach that captures the nuanced, multi-turn nature of conversation, for example, by applying methods from conversation analysis in discursive psychology. 5. Vichara: Appellate Judgment Prediction and Explanation for the Indian Judicial System 著者: Pavithra PM Nair, Preethu Rose Anish 公開日: 2026-02-20 ソース: arxiv arXiv ID: 2602.18346v1 要約 Vicharaは、インドの司法制度における控訴審判決の予測と説明を行う新しいフレームワークである。本フレームワークは英語の控訴審訴訟文書を「決定ポイント」(法的争点、判断主体、結果、理由、時間的文脈を含む離散的な法的判断)に分解し、構造化された表現によって正確な予測と解釈可能な説明を実現する。説明の生成にはIRAC(Issue-Rule-Application-Conclusion)フレームワークをインドの法的推論に適応させた構造化フォーマットを採用している。GPT-4o mini、Llama-3.1-8B、Mistral-7B、Qwen2.5-7Bの4つの大規模言語モデルを用いてPredExおよびILDC_expertデータセットで評価した結果、既存の判決予測ベンチマークを上回り、GPT-4o miniが最高性能(F1: PredExで81.5、ILDC_expertで80.3)を達成した。 原文Abstract In jurisdictions like India, where courts face an extensive backlog of cases, artificial intelligence offers transformative potential for legal judgment prediction. A critical subset of this backlog comprises appellate cases, which are formal decisions issued by higher courts reviewing the rulings of lower courts. To this end, we present Vichara, a novel framework tailored to the Indian judicial system that predicts and explains appellate judgments. Vichara processes English-language appellate case proceeding documents and decomposes them into decision points. Decision points are discrete legal determinations that encapsulate the legal issue, deciding authority, outcome, reasoning, and temporal context. The structured representation isolates the core determinations and their context, enabling accurate predictions and interpretable explanations. Vichara’s explanations follow a structured format inspired by the IRAC (Issue-Rule-Application-Conclusion) framework and adapted for Indian legal reasoning. This enhances interpretability, allowing legal professionals to assess the soundness of predictions efficiently. We evaluate Vichara on two datasets, PredEx and the expert-annotated subset of the Indian Legal Documents Corpus (ILDC_expert), using four large language models: GPT-4o mini, Llama-3.1-8B, Mistral-7B, and Qwen2.5-7B. Vichara surpasses existing judgment prediction benchmarks on both datasets, with GPT-4o mini achieving the highest performance (F1: 81.5 on PredEx, 80.3 on ILDC_expert), followed by Llama-3.1-8B. Human evaluation of the generated explanations across Clarity, Linking, and Usefulness metrics highlights GPT-4o mini’s superior interpretability. この記事は自動生成されています。論文の詳細は各ソースURLをご参照ください。 --- ### Snowflakeのディレクトリテーブルとメタデータ自動更新 date: 2024-05-17 url: https://zatoima.github.io/snowflake-directory-table-integration/ tags: Snowflake はじめに AWSのS3バケットとSnowflakeのディレクトリテーブル機能を使って、S3上のデータファイルの変更を自動的にSnowflakeのメタデータに反映させる方法についてやってみる。S3バケットへのファイルの追加・更新・削除を検知し、それをトリガーにしてSnowflakeのディレクトリテーブルのメタデータを最新の状態に保つことができる。 ディレクトリテーブルとは ディレクトリテーブルは、Snowflakeのステージ上のデータファイルに関するメタデータを格納するオブジェクトで、外部テーブルに似た概念で、ステージ内のファイルのパス、サイズ、最終更新日時などの情報を保持する ディレクトリテーブルを使うことで、以下のような非構造化データの処理が可能になる。 ステージ上の全ファイルのリストとメタデータのクエリ 非構造化データと構造化データを組み合わせたビューの作成 ファイル処理パイプラインの構築 ディレクトリテーブルのメタデータは、クラウドストレージのイベント通知と連携することで自動更新できる。これにより、ステージ上のファイルの追加・更新・削除を常にメタデータに反映させておくことが可能である。 今回はAWS上で実施してみる 前提条件 AWSアカウントとS3バケットが作成済みであること Snowflakeアカウントが作成済みであること S3バケットとSnowflakeを連携するためのストレージ統合が設定済みであること 手順 ステップ1: ディレクトリテーブル付きの外部ステージを作成 まず、S3バケットを指すSnowflakeの外部ステージを、ディレクトリテーブルオプションを指定して作成する CREATE STAGE mystage URL='s3://mybucket/path/' STORAGE_INTEGRATION = my_storage_int DIRECTORY = (ENABLE = true, AUTO_REFRESH = true); URLにはS3バケットのパスを指定 STORAGE_INTEGRATIONにはあらかじめ作成したストレージ統合オブジェクトを指定 DIRECTORYオプションでENABLE=trueとAUTO_REFRESH=trueを指定し、ディレクトリテーブルを有効化 ステップ2: 通知用SQSキューのARNを確認 ディレクトリテーブルの更新に使われるSQSキューのARN(Amazon Resource Name)を確認。 DESC STAGE mystage; を実行し、出力内の directory_notification_channel の値をコピーする。 ステップ3: S3バケットのイベント通知を設定 AWSマネジメントコンソールからS3バケットのプロパティ画面を開き、「イベント通知」の設定を実施 「イベント」で s3:ObjectCreated:Put と s3:ObjectRemoved:Delete を選択 「送信先」で SQS キュー を選択し、ステップ2でコピーしたSQSキューのARNを指定 これで、S3バケットへのオブジェクトの作成・削除が、指定したSQSキューへ通知されるようになる。 ステップ4: 初回のメタデータ更新を手動で実行 ALTER STAGE mystage REFRESH; コマンドを実行して、現時点でのS3バケットの状態をディレクトリテーブルに反映させる。この初回の手動更新が完了すると、以降はS3のイベント通知をトリガーに自動更新が行われるようになる。 ステップ5: アクセス権限の設定 ディレクトリテーブルをクエリするために必要な権限を、追加のロールに付与します。 データベースとスキーマに対する USAGE 権限 ステージに対する USAGE と READ 権限 ファイルフォーマットに対する USAGE 権限 ディレクトリテーブルの活用 ディレクトリテーブルのクエリ ディレクトリテーブルに対してSELECT文を実行することで、ステージ上の全ファイルのリストと、各ファイルのメタデータを取得できる。 SELECT * FROM DIRECTORY(@mystage); これにより、以下のような列が返される。 RELATIVE_PATH : ファイルへの相対パス SIZE : ファイルサイズ(バイト) LAST_MODIFIED : 最終更新日時 FILE_URL : ファイルへのSnowflake URL etc. 条件によるフィルタリングも可能である。 -- 100KBより大きいファイルのURLを取得 SELECT FILE_URL FROM DIRECTORY(@mystage) WHERE SIZE > 100000; -- CSVファイルのURLを取得 SELECT FILE_URL FROM DIRECTORY(@mystage) WHERE RELATIVE_PATH LIKE '%.csv'; ユースケース1:非構造化データのビュー作成 ディレクトリテーブルを他のテーブルと結合することで、ファイルのメタデータと他の情報を組み合わせた非構造化データのビューを作成できる。 例えば、PDFファイルを格納したステージ my_pdf_stage と、それらのメタデータテーブル report_metadata があるとする。FILE_URLをキーにしてJOINすることで、以下のようなビューが作成できる。 CREATE VIEW reports_information AS SELECT file_url AS report_link, author, publish_date, approved_date, geography, num_of_pages FROM directory(@my_pdf_stage) s JOIN report_metadata m ON s.file_url = m.file_url; このビューには、各PDFファイルのURLと、著者や公開日などの関連メタデータが含まれる。 ユースケース2:データ処理パイプラインの構築 ディレクトリテーブルをSnowflakeの他の機能と組み合わせることで、データ処理パイプラインを構築することもできる。 例えば、以下のようなステップでPDFファイルを処理するシンプルなパイプラインが作れる。 ディレクトリテーブル付きのステージ my_pdf_stage を作成 ディレクトリテーブルの変更を検知するストリーム my_pdf_stream を作成 PDFからデータを抽出するUDF PDF_PARSE を作成 抽出したデータを格納するテーブル prod_reviews を作成 ストリームをトリガーにタスク load_new_file_data を作成し、UDFを実行してテーブルにデータをロード ステージにPDFを追加すると、タスクが自動実行されてテーブルにデータが挿入される。prod_reviews をクエリすれば、PDFから抽出されたデータを参照できる。 ディレクトリテーブルでのストリームの作成 ディレクトリテーブルの変更を検知するために、Snowflakeストリームを作成することもできる。 CREATE STREAM dirtable_mystage_s ON STAGE mystage; ストリームにデータを流し込むには、ディレクトリテーブルのメタデータを手動更新する。 ALTER STAGE mystage REFRESH; ステージにファイルを追加した後、ストリームをクエリすると変更が確認できる。 SELECT * FROM dirtable_mystage_s; 出力: +-------------------+--------+-------------------------------+----------------------------------+----------------------------------+-------------------------------------------------------------------------------------------+-----------------+-------------------+-----------------+ | RELATIVE_PATH | SIZE | LAST_MODIFIED | MD5 | ETAG | FILE_URL | METADATA$ACTION | METADATA$ISUPDATE | METADATA$ROW_ID | |-------------------+--------+-------------------------------+----------------------------------+----------------------------------+-------------------------------------------------------------------------------------------+-----------------+-------------------+-----------------| | file1.csv.gz | 1048 | 2021-05-14 06:09:08.000 -0700 | c98f600c492c39bef249e2fcc7a4b6fe | c98f600c492c39bef249e2fcc7a4b6fe | https://myaccount.snowflakecomputing.com/api/files/MYDB/MYSCHEMA/MYSTAGE/file1%2ecsv%2egz | INSERT | False | | | file2.csv.gz | 3495 | 2021-05-14 06:09:09.000 -0700 | 7f1a4f98ef4c7c42a2974504d11b0e20 | 7f1a4f98ef4c7c42a2974504d11b0e20 | https://myaccount.snowflakecomputing.com/api/files/MYDB/MYSCHEMA/MYSTAGE/file2%2ecsv%2egz | INSERT | False | | +-------------------+--------+-------------------------------+------------------------------- このストリームを使って、ディレクトリテーブルへのファイルの追加・削除を検知し、さらなる処理をトリガーすることができる。 注意事項 S3イベント通知は、ディレクトリテーブルのメタデータ更新専用のSQSキューを指定する必要がある。他の用途と共用してはならない。 1つのS3バケットに対して作成できるイベント通知設定は最大100個までである。 同じS3バケットのプレフィックス(ディレクトリ)に対し、重複するイベント通知は作成できない。 Snowflakeのストレージ統合の設定で、S3バケットへの適切なアクセス権限を付与しておく必要がある。 SnowflakeのステージにENCRYPTION=(TYPE=‘SNOWFLAKE_SSE’)の設定が必要である。設定がないとダウンロードしたファイルが破損する可能性がある。 請求について ディレクトリテーブルのメタデータ自動更新に関する管理オーバーヘッドは、Snowpipeの料金として請求される。料金はステージに追加されるファイル数に応じて増加する。 PIPE_USAGE_HISTORY 関数や Account Usage PIPE_USAGE_HISTORY ビューで使用量を確認できる。 メタデータの手動更新(ALTER STAGE REFRESH)を行う場合も、若干の追加料金が発生する。 まとめ 以上の手順により、S3をデータソースとしSnowflakeのディレクトリテーブルを使う環境において、S3のファイル変更を自動的にメタデータに反映させることができる。 これにより、常に最新のデータに対してクエリを実行できるようになり、データパイプラインの自動化を促進できる。 ディレクトリテーブルは、ファイルのメタデータを他のテーブルと結合して活用することもでき、非構造化データを柔軟に扱うことができる。 また、ディレクトリテーブルの変更を検知するストリームを作成することで、リアルタイムにファイルの追加・削除を検知し、それをトリガーにしたデータ処理フローを構築することもできる。 参考資料 ディレクトリテーブルを使用したデータ処理パイプラインの構築 | Snowflake Documentation ディレクトリテーブルの自動化されたメタデータ更新 | Snowflake Documentation ディレクトリテーブルのクエリ | Snowflake Documentation --- ### PowerPoint for Macのフォントを一括置換するシェルスクリプト date: 2024-05-15 url: https://zatoima.github.io/Mac-pptx-font-replace/ tags: Mac はじめに MacのPPTのフォント置換がGUI上で動作しないケースが多々あるので下記2つの方法で一括置換を行っている。表の中のフォントなどは変わってくれないが、大部分は置き換わるはず。 シェルスクリプトによるフォント置換 最初の方法は、シェルスクリプトを使用してフォントを置換する方法で、このスクリプトでは、以下の処理を行う。 一時ディレクトリを作成し、.pptxファイルをコピーする .pptxファイルを解凍する ノート部分のテキストを削除する スライドのXMLファイル内のフォント情報を置換する 変更されたファイルを再度.pptxファイルにまとめる 変更された.pptxファイルを元の場所にコピーする このスクリプトを使用することで、カレントディレクトリ内の全ての.pptxファイルのフォントを一括で置換することができる。 #!/bin/bash set -eu TMP_DIR="$(mktemp -d)" echo "Created temporary directory: $TMP_DIR" trap 'rm -rf $TMP_DIR' EXIT for PPTX_FILE in *.pptx; do if [ -e "$PPTX_FILE" ]; then echo "Processing $PPTX_FILE..." cp "$PPTX_FILE" "$TMP_DIR" echo "Copied $PPTX_FILE to temporary directory." pushd "$TMP_DIR" echo "Changed directory to temporary directory." unzip "$PPTX_FILE" echo "Unzipped $PPTX_FILE." rm "$PPTX_FILE" echo "Removed original $PPTX_FILE from temporary directory." # フォント修正 find "./ppt/slides/"*.xml | xargs -I{} sed -i '' -e 's/typeface="[^"]*"/typeface="M PLUS 1p"/g' "{}" echo "Replaced typeface attributes with 'M PLUS 1p' in slide XML files." zip -0 -r "$PPTX_FILE" ./* # do not compress (-0) echo "Zipped modified files into $PPTX_FILE." popd echo "Returned to original directory." cp "$TMP_DIR/$PPTX_FILE" "$PPTX_FILE" echo "Copied modified $PPTX_FILE back to original location." else echo "File not found: $PPTX_FILE" fi done echo "Script execution completed." Pythonスクリプトによるフォント置換 次の方法は、Pythonスクリプトを使用してフォントを置換する方法である。このスクリプトでは、python-pptxライブラリを使用して以下の処理を行う。 カレントディレクトリ内の.pptxファイルを検索する 各.pptxファイル内で使用されているフォントを取得し、表示する ユーザが指定した新しいフォントで全てのテキストのフォントを置換する 変更された.pptxファイルを保存する Pythonスクリプトを使用する場合、python-pptxライブラリをインストールする必要がある。 import os from pptx import Presentation def get_used_fonts(ppt_file): prs = Presentation(ppt_file) used_fonts = set() for slide in prs.slides: for shape in slide.shapes: if shape.has_text_frame: for paragraph in shape.text_frame.paragraphs: for run in paragraph.runs: used_fonts.add(run.font.name) if shape.has_table: for row in shape.table.rows: for cell in row.cells: for paragraph in cell.text_frame.paragraphs: for run in paragraph.runs: used_fonts.add(run.font.name) return used_fonts def replace_fonts(ppt_file, new_font): prs = Presentation(ppt_file) for slide in prs.slides: for shape in slide.shapes: if shape.has_text_frame: for paragraph in shape.text_frame.paragraphs: for run in paragraph.runs: run.font.name = new_font if shape.has_table: table = shape.table for row in table.rows: for cell in row.cells: for paragraph in cell.text_frame.paragraphs: for run in paragraph.runs: run.font.name = new_font prs.save(ppt_file) def main(): current_dir = os.path.dirname(os.path.abspath(__file__)) ppt_files = [f for f in os.listdir(current_dir) if f.endswith('.pptx')] if not ppt_files: print("No PowerPoint files found in the current directory.") return print("Found PowerPoint files:") for ppt_file in ppt_files: print(ppt_file) used_fonts = get_used_fonts(os.path.join(current_dir, ppt_file)) print(f"Fonts used in {ppt_file}:") for font in used_fonts: print(f"- {font}") print() new_font = input("Enter the font name to replace all fonts with (default: 'M PLUS 1p'): ") if not new_font: new_font = 'M PLUS 1p' print(f"\nReplacing all fonts with '{new_font}' in all PowerPoint files...") for ppt_file in ppt_files: replace_fonts(os.path.join(current_dir, ppt_file), new_font) print("\nFont replacement completed.") if __name__ == '__main__': main() スクリプトの実行方法 シェルスクリプトの実行 スクリプトファイル(replacefontppt.sh)をカレントディレクトリに配置する ターミナルを開き、カレントディレクトリに移動する 以下のコマンドを実行してスクリプトを実行する ./replacefontppt.sh Pythonスクリプトの実行 ライブラリをインストールする pip install python-pptx スクリプトファイル(replacefontppt.py)をカレントディレクトリに配置する ターミナルを開き、カレントディレクトリに移動する 以下のコマンドを実行してスクリプトを実行する python replacefontppt.py --- ### SnowCLIを使用したデータのアンロード/アップロード date: 2024-05-02 url: https://zatoima.github.io/snowflake-snowcli-data-unload-upload/ tags: Snowflake 前提条件 CLIツールのインストール: SnowSQLのインストール SnowCLIのインストール サンプルデータベースの有効化 サンプルデータベースの使用 https://docs.snowflake.com/ja/user-guide/sample-data-using 手順 作業用ディレクトリを削除し、再作成 #rm -rf ~/work/temp/upload mkdir -p ~/work/temp/upload SnowSQLを使用して新しいデータベースを作成 snow sql -q 'create or replace database sandbox'; 新しいステージを作成 snow object stage create sandbox.public.my_stage; 指定されたフォーマットでデータをステージにアンロード snow sql -q 'copy into @sandbox.public.my_stage/data.csv from (select * from SNOWFLAKE_SAMPLE_DATA.TPCH_SF1.LINEITEM limit 1000) file_format = (format_name = CSV_FORMAT compression = NONE) SINGLE=TRUE HEADER=TRUE OVERWRITE = TRUE'; ステージ内のファイルリストを表示 snow object stage list @sandbox.public.my_stage ステージからローカルのディレクトリにファイルをコピー cd ~/work/temp/upload snow object stage copy @sandbox.public.my_stage . ローカルからステージへファイルをアップロード(SnowCLIを使用) snow object stage copy data.csv @sandbox.public.my_stage ローカルファイルをステージにアップロード(SnowSQLを使用) ※ログインは省略 use database sandbox; put file://~/work/temp/upload/* @my_stage; 参照 Snowflake CLI | Snowflake Documentation snowflakedb/snowflake-cli: Snowflake CLI is an open-source command-line tool explicitly designed for developer-centric workloads in addition to SQL operations. --- ### GA4のデータをPython(Analytics Data API)で取得する date: 2024-04-30 url: https://zatoima.github.io/ga4-data-analytics-api-python/ tags: python はじめに PythonのAnalytics Data APIを利用すると、GA4のデータを柔軟に取得し、分析やレポーティングに活用できる。GA4のデータをPythonから扱ってHugoの静的ジェネレーターに貼り付けるためのステップを検討。 Analytics Data APIとは Analytics Data APIは、GA4のデータにプログラムでアクセスするためのAPI。レポートのデータを取得したり、カスタムレポートを作成したりできる。GCPの使用が前提でアカウントは必須な模様。 Pythonでの利用方法 PythonからAnalytics Data APIを使う場合、google-api-python-clientとgoogle-analytics-data パッケージを利用する。 pip install google-api-python-client pip install google-analytics-data Analytics Data APIの有効化 https://developers.google.com/analytics/devguides/reporting/data/v1/quickstart-client-libraries?hl=ja API を有効にする Cloud Platform プロジェクトを作成し、Google Analytics Data API v1 を有効にする credentials.json ファイルをダウンロードし、作業ディレクトリに保存する Google アナリティクス 4 プロパティにサービス アカウントを追加する credentials.json ファイルから client_email フィールドのサービス アカウントのメールアドレスを取得する 取得したメールアドレスを使用して、Google アナリティクス 4 プロパティにユーザーを追加する(閲覧者権限のみ) 認証を構成する サービス アカウントの認証情報を指定するために、GOOGLE_APPLICATION_CREDENTIALS 環境変数を設定する 環境変数の値として、ステップ 1 でダウンロードしたサービス アカウント JSON ファイルのパスを指定する クライアント ライブラリをインストールする 選択したプログラミング言語に応じて、Google Analytics Data API のクライアント ライブラリをインストールする API 呼び出しを行う 認証とクライアント ライブラリのセットアップが完了したら、Google Analytics Data API を使用して Google アナリティクス 4 プロパティにクエリを実行する credentials.jsonの名前をga4_prifile.jsonに変更した。 環境変数の設定 export GOOGLE_APPLICATION_CREDENTIALS=./ga4_prifile.json export GA_PROPERTY_ID=384740337 パッケージのインストールと環境変数を設定後、以下のようにAPIを呼び出してレポートデータを取得できる。 import os from google.analytics.data_v1beta import BetaAnalyticsDataClient from google.analytics.data_v1beta.types import DateRange from google.analytics.data_v1beta.types import Dimension from google.analytics.data_v1beta.types import Metric from google.analytics.data_v1beta.types import RunReportRequest def run_report(property_id): client = BetaAnalyticsDataClient() request = RunReportRequest( property=f"properties/{property_id}", dimensions=[Dimension(name="date")], metrics=[Metric(name="sessions")], date_ranges=[DateRange(start_date="365daysAgo", end_date="today")], ) response = client.run_report(request) print("Report result:") for row in response.rows: print(row.dimension_values[0].value, row.metric_values[0].value) def main(): ga_property_id = os.environ['GA_PROPERTY_ID'] run_report(ga_property_id) if __name__ == "__main__": main() このスクリプトでは、過去1年間のページ別のページビュー数を、ページビューの多い順に15件取得。 アウトプット Most viewed articles in the last year: 10713 views: PostgreSQLのpg_dump、pg_restoreについてまとめる 6917 views: Excelのグラフで横軸を1時間ごとのグラフにする方法 4065 views: MySQLのFLUSH PRIVILEGESが必要なケース 3971 views: Auroraの各バージョンのサポート期間 3616 views: EC2上からpsqlでAurora(PostgreSQL)に接続するまで 3573 views: PostgreSQLでfunctionの定義を確認する方法 2768 views: OracleとPostgreSQL(+Redshift)のchar、varcharのバイトと文字数の違い 2720 views: Data Pump(expdp/impdp)使用時のコマンドとオプション 2610 views: PostgreSQLの監視のためのログ設定について 2385 views: いまいちどOracle Databaseのデータ移行方法について考えてみる 2193 views: PostgreSQLでja_JP.UTF-8のデータベース作成時のlocaleエラー 2115 views: サーバ側と通信するCipher suite (暗号スイート) の調査方法 2060 views: PostgreSQLの自動Vacuumの実行タイミングと関連するパラメータ 1940 views: PostgreSQLで月初、月末日、翌月月初を取得する 1709 views: S3オブジェクトのmd5やEtagの関係性について整理する --- ### PowerPoint for Macのノートを一括削除するシェルスクリプト date: 2024-04-26 url: https://zatoima.github.io/mac-pptx-delete-note/ tags: Mac はじめに PowerPointのプレゼンテーションファイル(*.pptx)には、各スライドにノートを追加することができる。 ただ、このノートを一括で削除する機能はMac版のPowerPoint本体には備わっていない(はず)。 今回は、シェルスクリプトを用いてこのノート削除を自動化してみる。 シェルスクリプトの説明 このシェルスクリプト(delete_note.sh)は、以下のような処理を行う。 一時ディレクトリを作成し、そのパスをTMP_DIR変数に格納する。 カレントディレクトリ内の全てのpptxファイルに対して、以下の処理を行う。 .pptxファイルを一時ディレクトリにコピーする。 一時ディレクトリ内で.pptxファイルを解凍する。 ./ppt/notesSlides/ディレクトリ内の全ての.xmlファイルに対して、`<a:t>タグの内容を空にする。 解凍したファイルを再度.pptxファイルにまとめる。 生成された.pptxファイルを元のディレクトリにコピーする。 一時ディレクトリを削除する。 シェルスクリプト #!/bin/bash set -eu TMP_DIR="$(mktemp -d)" trap 'rm -rf $TMP_DIR' EXIT for PPTX_FILE in *.pptx; do if [ -e "$PPTX_FILE" ]; then echo "Processing $PPTX_FILE..." cp "$PPTX_FILE" "$TMP_DIR" pushd "$TMP_DIR" unzip "$PPTX_FILE" rm "$PPTX_FILE" find "./ppt/notesSlides/"*.xml | xargs -I{} sed -i '' -e 's/<a:t>[^<]*<\/a:t>/<a:t><\/a:t>/g' "{}" zip -0 -r "$PPTX_FILE" ./* # do not compress (-0) popd cp "$TMP_DIR/$PPTX_FILE" "$PPTX_FILE" fi done 前提:PPTXファイルの構造 PPTXファイルは、実際にはXMLファイルの集合体である。 具体的には、以下のような構造になっている。 _rels/: リレーションシップを定義するXMLファイルを格納するディレクトリ。 docProps/: ドキュメントのプロパティを定義するXMLファイルを格納するディレクトリ。 pptx プレゼンテーションの本体を構成するXMLファイルを格納するディレクトリ。 slides/: 各スライドの情報を格納するXMLファイルを格納するディレクトリ。 slideMasters/: スライドマスターの情報を格納するXMLファイルを格納するディレクトリ。 notesMasters/: ノートマスターの情報を格納するXMLファイルを格納するディレクトリ。 notesSlides/: 各スライドのノートの情報を格納するXMLファイルを格納するディレクトリ。 theme/: テーマの情報を格納するXMLファイルを格納するディレクトリ。 _rels/: リレーションシップを定義するXMLファイルを格納するディレクトリ。 [Content_Types].xml: コンテンツタイプを定義するXMLファイル。 これらのXMLファイルが圧縮されたものが、PPTXファイルとなる。 つまり、PPTXファイルを編集するには、一度解凍してXMLファイルを修正し、再度圧縮する必要がある。この構造が知っていないとMac版のPPTを運用していく際は詰む。 --- ### M1 MacにPostgreSQLをインストールする date: 2023-02-10 url: https://zatoima.github.io/postgres-mac-install-postgresql-homebrew/ tags: PostgreSQL 前提 Homebrewがインストールされていること インストール (base) jimazato@XXXXXXXX ~ % brew search postgresql ==> Formulae postgresql@10 postgresql@11 postgresql@12 postgresql@13 postgresql@14 postgresql@15 postgresql@9.4 postgresql@9.5 qt-postgresql postgrest ==> Casks navicat-for-postgresql If you meant "postgresql" specifically: postgresql breaks existing databases on upgrade without human intervention. See a more specific version to install with: brew formulae | grep postgresql@ (base) jimazato@XXXXXXXX ~ % brew install postgresql Running `brew update --auto-update`... ==> Auto-updated Homebrew! Updated 4 taps (hashicorp/tap, homebrew/core, homebrew/cask and homebrew/services). 省略 バージョン確認 (base) jimazato@XXXXXXXX ~ % psql --version psql (PostgreSQL) 14.7 (Homebrew) Linuxの場合、pgbenchはpostgresql-contribのインストールが必要だったが、Homebrewの場合は一緒にインストールされるらしい。 (base) jimazato@XXXXXXXX ~ % pgbench --version pgbench (PostgreSQL) 14.7 (Homebrew) AWSのRDSに接続してpgbench(データ生成のみ)を実施してみる (base) jimazato@XXXXXXXX ~ % psql -h xxxx-rds-pgsql.xxxxxx.us-west-1.rds.amazonaws.com -U postgres -d postgres Password for user postgres: psql (14.7 (Homebrew), server 13.7) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) Type "help" for help. postgres=> select version(); version --------------------------------------------------------------------------------------------------------- PostgreSQL 13.7 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-12), 64-bit (1 row) (base) jimazato@XXXXXXXX ~ % pgbench -r -c 10 -j 10 -t 10 -U postgres -h xxxx-rds-pgsql.xxxxxx.us-west-1.rds.amazonaws.com pgbench pgbench (14.7 (Homebrew), server 13.7) starting vacuum...end. transaction type: <builtin: TPC-B (sort of)> scaling factor: 10 query mode: simple number of clients: 10 number of threads: 10 number of transactions per client: 10 number of transactions actually processed: 100/100 latency average = 1095.176 ms initial connection time = 858.293 ms tps = 9.130952 (without initial connection time) statement latencies in milliseconds: 0.005 \set aid random(1, 100000 * :scale) 0.002 \set bid random(1, 1 * :scale) 0.001 \set tid random(1, 10 * :scale) 0.001 \set delta random(-5000, 5000) 134.627 BEGIN; 136.454 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid; 135.479 SELECT abalance FROM pgbench_accounts WHERE aid = :aid; 145.459 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid; 193.648 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid; 134.604 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP); 135.139 END; --- ### Lambdaで一向にCloudWatch logsのログが書き込まれない時の確認ポイント date: 2023-01-27 url: https://zatoima.github.io/aws-lambda-cloudwatch-logs-not-write/ tags: AWS こんなエラーが出て一向にログが書き込まれない 原因 他のLamdba関数のロールを使いまわしており、CloudWatch logsの書き込み先が特定のLamdba用になっていたため。IAMポリシーを書き換えるか、新規でポリシーを作ることで解決出来る。 --- ### SQL APIを使用してSnowflakeにSQLを発行する date: 2023-01-11 url: https://zatoima.github.io/snowflake-sql-api-try/ tags: Snowflake キーペア認証を使用して接続可能なユーザを作成 cd ~/.ssh openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out snowflake_tf_snow_key.p8 -nocrypt openssl rsa -in snowflake_tf_snow_key.p8 -pubout -out snowflake_tf_snow_key.pub snowflake_tf_snow_key.pubの文字列を取得して次のSQLのRSA_PUBLIC_KEY_HEREに貼り付ける。 CREATE USER sqlapiuser RSA_PUBLIC_KEY='RSA_PUBLIC_KEY_HERE' DEFAULT_ROLE=PUBLIC MUST_CHANGE_PASSWORD=FALSE; -- CREATE USER sqlapiuser RSA_PUBLIC_KEY='MIIBXnmXXXXXXXXXXXXXXXXXXf7Z4EqXXXXXXXXXXXB' DEFAULT_ROLE=PUBLIC MUST_CHANGE_PASSWORD=FALSE; GRANT ROLE SYSADMIN TO USER sqlapiuser; 接続確認を行う snowsql -a <ACCOUNT名> -u sqlapiuser --private-key-path /Users/jimazato/.ssh/snowflake_tf_snow_key.p8 JWT生成を行う 下記マニュアルにも記載がある通り、リクエスト用の認証情報である JSON Web トークン(JWT)を生成する Authenticating to the Server for the SQL API — Snowflake Documentation sql-api-generate-jwt.pyとして保存する。 # To run this on the command line, enter: # python3 sql-api-generate-jwt.py --account=<account_identifier> --user=<username> --private_key_file_path=<path_to_private_key_file> from cryptography.hazmat.primitives.serialization import load_pem_private_key from cryptography.hazmat.primitives.serialization import Encoding from cryptography.hazmat.primitives.serialization import PublicFormat from cryptography.hazmat.backends import default_backend from datetime import timedelta, timezone, datetime import argparse import base64 from getpass import getpass import hashlib import logging import sys # This class relies on the PyJWT module (https://pypi.org/project/PyJWT/). import jwt logger = logging.getLogger(__name__) try: from typing import Text except ImportError: logger.debug('# Python 3.5.0 and 3.5.1 have incompatible typing modules.', exc_info=True) from typing_extensions import Text ISSUER = "iss" EXPIRE_TIME = "exp" ISSUE_TIME = "iat" SUBJECT = "sub" # If you generated an encrypted private key, implement this method to return # the passphrase for decrypting your private key. As an example, this function # prompts the user for the passphrase. def get_private_key_passphrase(): return getpass('Passphrase for private key: ') class JWTGenerator(object): """ Creates and signs a JWT with the specified private key file, username, and account identifier. The JWTGenerator keeps the generated token and only regenerates the token if a specified period of time has passed. """ LIFETIME = timedelta(minutes=59) # The tokens will have a 59 minute lifetime RENEWAL_DELTA = timedelta(minutes=54) # Tokens will be renewed after 54 minutes ALGORITHM = "RS256" # Tokens will be generated using RSA with SHA256 def __init__(self, account: Text, user: Text, private_key_file_path: Text, lifetime: timedelta = LIFETIME, renewal_delay: timedelta = RENEWAL_DELTA): """ __init__ creates an object that generates JWTs for the specified user, account identifier, and private key. :param account: Your Snowflake account identifier. See https://docs.snowflake.com/en/user-guide/admin-account-identifier.html. Note that if you are using the account locator, exclude any region information from the account locator. :param user: The Snowflake username. :param private_key_file_path: Path to the private key file used for signing the JWTs. :param lifetime: The number of minutes (as a timedelta) during which the key will be valid. :param renewal_delay: The number of minutes (as a timedelta) from now after which the JWT generator should renew the JWT. """ logger.info( """Creating JWTGenerator with arguments account : %s, user : %s, lifetime : %s, renewal_delay : %s""", account, user, lifetime, renewal_delay) # Construct the fully qualified name of the user in uppercase. self.account = self.prepare_account_name_for_jwt(account) self.user = user.upper() self.qualified_username = self.account + "." + self.user self.lifetime = lifetime self.renewal_delay = renewal_delay self.private_key_file_path = private_key_file_path self.renew_time = datetime.now(timezone.utc) self.token = None # Load the private key from the specified file. with open(self.private_key_file_path, 'rb') as pem_in: pemlines = pem_in.read() try: # Try to access the private key without a passphrase. self.private_key = load_pem_private_key(pemlines, None, default_backend()) except TypeError: # If that fails, provide the passphrase returned from get_private_key_passphrase(). self.private_key = load_pem_private_key(pemlines, get_private_key_passphrase().encode(), default_backend()) def prepare_account_name_for_jwt(self, raw_account: Text) -> Text: """ Prepare the account identifier for use in the JWT. For the JWT, the account identifier must not include the subdomain or any region or cloud provider information. :param raw_account: The specified account identifier. :return: The account identifier in a form that can be used to generate JWT. """ account = raw_account if not '.global' in account: # Handle the general case. idx = account.find('.') if idx > 0: account = account[0:idx] else: # Handle the replication case. idx = account.find('-') if idx > 0: account = account[0:idx] # Use uppercase for the account identifier. return account.upper() def get_token(self) -> Text: """ Generates a new JWT. If a JWT has been already been generated earlier, return the previously generated token unless the specified renewal time has passed. :return: the new token """ now = datetime.now(timezone.utc) # Fetch the current time # If the token has expired or doesn't exist, regenerate the token. if self.token is None or self.renew_time <= now: logger.info("Generating a new token because the present time (%s) is later than the renewal time (%s)", now, self.renew_time) # Calculate the next time we need to renew the token. self.renew_time = now + self.renewal_delay # Prepare the fields for the payload. # Generate the public key fingerprint for the issuer in the payload. public_key_fp = self.calculate_public_key_fingerprint(self.private_key) # Create our payload payload = { # Set the issuer to the fully qualified username concatenated with the public key fingerprint. ISSUER: self.qualified_username + '.' + public_key_fp, # Set the subject to the fully qualified username. SUBJECT: self.qualified_username, # Set the issue time to now. ISSUE_TIME: now, # Set the expiration time, based on the lifetime specified for this object. EXPIRE_TIME: now + self.lifetime } # Regenerate the actual token token = jwt.encode(payload, key=self.private_key, algorithm=JWTGenerator.ALGORITHM) # If you are using a version of PyJWT prior to 2.0, jwt.encode returns a byte string, rather than a string. # If the token is a byte string, convert it to a string. if isinstance(token, bytes): token = token.decode('utf-8') self.token = token logger.info("Generated a JWT with the following payload: %s", jwt.decode(self.token, key=self.private_key.public_key(), algorithms=[JWTGenerator.ALGORITHM])) return self.token def calculate_public_key_fingerprint(self, private_key: Text) -> Text: """ Given a private key in PEM format, return the public key fingerprint. :param private_key: private key string :return: public key fingerprint """ # Get the raw bytes of public key. public_key_raw = private_key.public_key().public_bytes(Encoding.DER, PublicFormat.SubjectPublicKeyInfo) # Get the sha256 hash of the raw bytes. sha256hash = hashlib.sha256() sha256hash.update(public_key_raw) # Base64-encode the value and prepend the prefix 'SHA256:'. public_key_fp = 'SHA256:' + base64.b64encode(sha256hash.digest()).decode('utf-8') logger.info("Public key fingerprint is %s", public_key_fp) return public_key_fp def main(): logging.basicConfig(stream=sys.stdout, level=logging.INFO) cli_parser = argparse.ArgumentParser() cli_parser.add_argument('--account', required=True, help='The account identifier (e.g. "myorganization-myaccount" for "myorganization-myaccount.snowflakecomputing.com").') cli_parser.add_argument('--user', required=True, help='The user name.') cli_parser.add_argument('--private_key_file_path', required=True, help='Path to the private key file used for signing the JWT.') cli_parser.add_argument('--lifetime', type=int, default=59, help='The number of minutes that the JWT should be valid for.') cli_parser.add_argument('--renewal_delay', type=int, default=54, help='The number of minutes before the JWT generator should produce a new JWT.') args = cli_parser.parse_args() token = JWTGenerator(args.account, args.user, args.private_key_file_path, timedelta(minutes=args.lifetime), timedelta(minutes=args.renewal_delay)).get_token() print('JWT:') print(token) if __name__ == "__main__": main() 引数にアカウント識別子やSnowflakeのユーザ、最初に作成した秘密鍵のパスを指定する。 python3 sql-api-generate-jwt.py --account=<ACCOUNT名> --user=sqlapiuser --private_key_file_path=/Users/jimazato/.ssh/snowflake_tf_snow_key.p8 (base) jimazato@CJ2VQ9Y2M1 sqlapi % python3 sql-api-generate-jwt.py --account=<ACCOUNT名> --user=sqlapiuser --private_key_file_path=/Users/jimazato/.ssh/snowflake_tf_snow_key.p8 INFO:__main__:Creating JWTGenerator with arguments account : <ACCOUNT名>, user : sqlapiuser, lifetime : 0:59:00, renewal_delay : 0:54:00 INFO:__main__:Generating a new token because the present time (2022-12-28 07:00:24.553334+00:00) is later than the renewal time (2022-12-28 07:00:24.508806+00:00) INFO:__main__:Public key fingerprint is SHA256:maG2a3wOxVnX0cGmhc5SRmWpRzzK5JuNjUm98JRGa1k= INFO:__main__:Generated a JWT with the following payload: {'iss': '<ACCOUNT名>.sqlapiuser.SHA256:maG2a3wOxVnX0cGmhc5SRmWpRzzK5JuNjUm98JRGa1k=', 'sub': '<ACCOUNT名>.sqlapiuser', 'iat': 1672210824, 'exp': 1672214364} JWT: eyJ0 (省略) ixwFE-Ww Curlでリクエスト発行。JWTのところで出力された文字列をAuthorization: Bearerに指定する。 curl -i -X POST \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <ここにJWTの値を貼り付けて実行>" \ -H "Accept: application/json" \ -H "User-Agent: myApplicationName/1.0" \ -H "X-Snowflake-Authorization-Token-Type: KEYPAIR_JWT" \ -d "{\"statement\": \"SELECT CURRENT_REGION()\"}" \ "https://<ACCOUNT名>.snowflakecomputing.com/api/v2/statements" レスポンス結果 HTTP/1.1 200 OK Content-Type: application/json Date: Wed, 28 Dec 2022 07:15:28 GMT Expect-CT: enforce, max-age=3600 Link: </api/v2/statements/01a943f3-0000-a91b-0000-a6f10012c07a?requestId=9c8671e3-9d0a-47a3-998e-9f01472d6435&partition=0>; rel="first",</api/v2/statements/01a943f3-0000-a91b-0000-a6f10012c07a?requestId=a7facb2c-4fc3-4503-9d08-bab3ed427c27&partition=0>; rel="last" Strict-Transport-Security: max-age=31536000 Vary: Accept-Encoding, User-Agent X-Content-Type-Options: nosniff X-Country: Japan X-Frame-Options: deny X-XSS-Protection: : 1; mode=block Content-Length: 891 Connection: keep-alive { "resultSetMetaData" : { "numRows" : 1, "format" : "jsonv2", "partitionInfo" : [ { "rowCount" : 1, "uncompressedSize" : 29 } ], "rowType" : [ { "name" : "CURRENT_REGION()", "database" : "", "schema" : "", "table" : "", "byteLength" : 16777216, "type" : "text", "scale" : null, "precision" : null, "nullable" : true, "collation" : null, "length" : 16777216 } ] }, "data" : [ ["PUBLIC.AWS_AP_NORTHEAST_1"] ], "code" : "090001", "statementStatusUrl" : "/api/v2/statements/01a943f3-0000-a91b-0000-a6f10012c07a?requestId=10c8547f-3a93-438a-88f1-94788ec3755e", "requestId" : "10c8547f-3a93-438a-88f1-94788ec3755e", "sqlState" : "00000", "statementHandle" : "01a943f3-0000-a91b-0000-a6f10012c07a", "message" : "Statement executed successfully.", "createdOn" : 1672211728759 参考 Snowflake SQL API — Snowflake Documentation --- ### snowflake-connector-pythonをLambdaで使用する事前準備メモ date: 2023-01-04 url: https://zatoima.github.io/snowflake-connector-python-lambda-use/ tags: AWS はじめに snowflake-connector-pythonのようなLambdaで対応していないPythonライブラリを使用したい場合、下記のいずれかの方法を使用してLambdaを構成する必要がある。 zip ファイルアーカイブ Lambdaレイヤー コンテナ ネット上にあった方法で実行したところ、下記のエラーに悩まされ、1.zip ファイルアーカイブや2.Lambdaレイヤーのいずれも想定通りに動作しなかったので方法1と2のDockerを使ったzipファイルアーカイブ方法やLambdaレイヤー作成方法をメモしておく。 AWS Lambda: Unable to import module ‘python_handler’: No module named ‘_cffi_backend’ 原因については、amazonlinuxのイメージではNGでaws-sam-cli-build-image-python3.8ではOKだったので、環境準備が不十分だったと思っている。 ここに至るまでに試した方法は下記の通り。 Lambda から Snowflake にシュッとつなぎたい! - Qiita Lambda packaging the right way - OzNetNerd.com python - AWS Lambda: Unable to import module ‘python_handler’: No module named ‘_cffi_backend’ - Stack Overflow 実行環境 (base) jimazato@CJ2VQ9Y2M1 ~ % sw_vers ProductName: macOS ProductVersion: 13.0.1 BuildVersion: 22A400 (base) jimazato@CJ2VQ9Y2M1 ~ % docker --version Docker version 20.10.21, build baeda1f (base) jimazato@CJ2VQ9Y2M1 ~ % docker-compose --version Docker Compose version v2.13.0 方法1:zip ファイルアーカイブを使用する ファイルの配置 base) jimazato@CJ2VQ9Y2M1 snow_lambda_zip % tree . ├── Dockerfile ├── docker-compose.yml ├── lambda_function.py └── requirements.txt Dockerfile ※ArmアーキテクチャのM1 Mac上でx86_64向けのPython環境を動作させるため、明示的に--platformを指定 aws-sam-cli-build-image-pythonはLamdbaで動作している環境とほぼ同一のようなので、イメージとして非常に大きい。なお、ここでイメージ指定を例えばamazonlinux:latestにした場合、上記で記載したAWS Lambda: Unable to import module 'python_handler': No module named '_cffi_backend'が自分の環境で出てしまった。 FROM --platform=linux/x86_64 amazon/aws-sam-cli-build-image-python3.8:latest RUN yum update -y RUN yum install python3 -y RUN pip3 install virtualenv RUN yum install zip -y RUN yum -y install gcc openssl-devel bzip2-devel libffi-devel zip docker-compose.yml ※ArmアーキテクチャのM1 Mac上でx86_64向けのPython環境を動作させるため、明示的に--platformを指定 version: '2' services: app_zip: build: . platform: linux/x86_64 volumes: - '.:/var/task' working_dir: /var/task command: > bash -c 'virtualenv env && source env/bin/activate && mkdir -p snow_lambda && cd ./snow_lambda && pip3 install -r ../requirements.txt -t . && zip -9 ../snow_lambda.zip ../lambda_function.py && zip -r9 /var/task/snow_lambda.zip .' requirements.txt snowflake-connector-python lambda_function.py 中身は省略 コマンド docker-compose build --no-cache docker-compose up -d snow_lambda.zipがカレントディレクトリに出来るので、これをLambdaにアップロードして実行する。 (base) jimazato@CJ2VQ9Y2M1 snow_lambda_zip % ls -l total 67640 -rw-r--r--@ 1 jimazato staff 300 1 1 16:13 Dockerfile -rw-r--r--@ 1 jimazato staff 419 1 4 09:14 docker-compose.yml drwxr-xr-x@ 6 jimazato staff 192 1 4 10:04 env -rw-r--r--@ 1 jimazato staff 1335 1 1 15:14 lambda_function.py -rw-r--r--@ 1 jimazato staff 27 1 1 15:30 requirements.txt drwxr-xr-x@ 44 jimazato staff 1408 1 4 10:05 snow_lambda -rw-r--r--@ 1 jimazato staff 34570052 1 4 10:05 snow_lambda.zip 参考 .zip ファイルアーカイブで Python Lambda 関数をデプロイする - AWS Lambda 方法2:Lambdaレイヤーを使用する ファイルの配置 base) jimazato@CJ2VQ9Y2M1 snow_lambda_zip % tree . ├── Dockerfile ├── docker-compose.yml └── requirements.txt Dockerfile 方法1とDockerファイルは変わらない。 ※ArmアーキテクチャのM1 Mac上でx86_64向けのPython環境を動作させるため、明示的に--platformを指定 FROM --platform=linux/x86_64 amazon/aws-sam-cli-build-image-python3.8:latest RUN yum update -y RUN yum install python3 -y RUN pip3 install virtualenv RUN yum install zip -y RUN yum -y install gcc openssl-devel bzip2-devel libffi-devel zip docker-compose.yml 方法1とほぼ一緒のコマンドとなるが、lambda_function.pyはLambdaレイヤーには不要なので入れていないのと、/opt/python/配下に各ライブラリが配置されるように微修正。 ※ArmアーキテクチャのM1 Mac上でx86_64向けのPython環境を動作させるため、明示的に--platformを指定 version: '2' services: app_layer: build: . platform: linux/x86_64 volumes: - '.:/var/task' working_dir: /var/task command: > bash -c 'virtualenv env && source env/bin/activate && mkdir -p python && pip3 install -r requirements.txt -t ./python && zip -r9 /var/task/layer.zip python' requirements.txt snowflake-connector-python コマンド docker-compose build --no-cache docker-compose up -d layer.zipがカレントディレクトリに出来るので、これをLambdaレイヤーにアップロードして実行する。 (base) jimazato@CJ2VQ9Y2M1 snow_lambda_layer % ls -l total 67632 -rw-r--r--@ 1 jimazato staff 300 1 1 16:13 Dockerfile -rw-r--r--@ 1 jimazato staff 336 1 1 22:53 docker-compose.yml drwxr-xr-x@ 6 jimazato staff 192 1 4 10:06 env -rw-r--r--@ 1 jimazato staff 1335 1 1 15:14 lambda_function.py -rw-r--r--@ 1 jimazato staff 34608594 1 4 10:08 layer.zip drwxr-xr-x@ 44 jimazato staff 1408 1 4 10:07 python -rw-r--r--@ 1 jimazato staff 27 1 1 15:30 requirements.txt 参考 Lambda レイヤーの作成と共有 - AWS Lambda AWS Lambda Layersでライブラリを共通化 - Qiita 追記(2026-02-23) 本記事の執筆時点ではPython 3.8を使用していましたが、以下の点にご注意ください。 Python 3.8はAWS Lambdaで非推奨・サポート終了済み:2025年2月以降、Python 3.8での新規Lambda関数の作成はできなくなっています。現在はPython 3.13が最新のサポートランタイムです。新規で構築する場合はaws-sam-cli-build-image-python3.12以降のイメージを使用してください Docker Compose V1(docker-composeコマンド)は非推奨:2023年7月にサポート終了しています。docker compose(ハイフンなし)コマンドに移行してください docker-compose.ymlのversionフィールドは不要:Docker Compose V2ではCompose Specificationが採用され、versionキーは無視されます。削除しても問題ありません --- ### GASでGmailから件名やメールアドレスを抽出する date: 2023-01-02 url: https://zatoima.github.io/gas-mail-address-list/ tags: GAS プライベートのメールでほぼ見ないメールはArchiveラベルをつけて受信トレイをSkipする運用にしている。これをやるためにはフィルタリングを行う必要があるのだが、メールアドレスの抽出時にOutlookのエクスポート -> メールアドレス抽出という手順を踏んでいた。これを簡略化したくて、抽出したいメールをスターをつけておいて、必要なときにこのGASを実行して、メールアドレスを一覧化したのでメモしておく。 コード こちらのサイトのスクリプトにメールアドレス"だけ"を抽出するファンクションを追加したり検索条件を変えただけ。 Gmailの検索と内容取得をするGAS – TD シネックスブログ function searchMails() { const query = 'is:starred' const threads = GmailApp.search(query); const ss = SpreadsheetApp.getActiveSpreadsheet(); const sheet = ss.getSheetByName('メールリスト'); // 削除の開始行と削除する行数を取得(詳細後述) const rowPosition = 2; const howMany = sheet.getLastRow() - 1; // データの行がある場合、行削除を実行(詳細後述) if(howMany > 0){ sheet.deleteRows(rowPosition, howMany); } // 送信元からメールアドレスを抽出するための正規表現定義 const emailRe = new RegExp("[a-zA-Z0-9_.+-]+@([a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]*.)+[a-zA-Z]{2,}"); // 送信元からメールアドレスを抽出するためのファンクション function emailOf(s) { const m = s.match(emailRe); if (m) { // m != null return m[0]; } return ""; } threads.forEach(thread => { const messages = thread.getMessages(); messages.forEach(message => { let fromData = message.getFrom(); // 送信元 let subject = message.getSubject(); // 件名 //let body = message.getPlainBody(); // 本文 let attachments = message.getAttachments(); // 添付ファイル群(配列) let fromAdress= emailOf(fromData); //メールアドレス let attachmentList = []; // 添付ファイルのファイル名格納用の配列 if(attachments.length > 0){ attachments.forEach(attachment => { let name = attachment.getName(); attachmentList.push(name); }); } attachmentList = attachmentList.join(','); let data = [fromData, fromAdress, subject, attachmentList]; //本文が必要な場合はbodyの変数を追加 sheet.appendRow(data); }); }); } スプレッドシート側 事前にやることとして、メールリストというシート名とヘッダーを用意する。 --- ### Githubの.gitignoreとgit-secrets設定 date: 2022-12-28 url: https://zatoima.github.io/github-gitignore-git-secrets-setting/ tags: Github AWSアクセスキーを誤ってコミットしないための設定 https://kakakakakku.hatenablog.com/entry/2017/02/06/100706 cd /Users/jimazato/work/hugo/zatoima.github.io brew install git-secrets git secrets --install git secrets --register-aws git config -l | grep secrets AWSのアカウント番号等も追加 アカウント番号は一意となってしまうので誤ってPushしないように設定する。 git secrets --add 'XXXXXXXX' git config -l | grep secrets .gitignoreへの追加 ぼくのかんがえたさいきょうの .gitignore - Qiita cat << EOF > .gitignore # Project Specific rules here # Temporary Files #--------------------------- # vim [._]*.s[a-w][a-z] [._]s[a-w][a-z] *.un~ Session.vim .netrwhist # Emacs .\#* # Backup files #--------------------------- *~ *.orig *.bak # yyyyMMdd *.[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] # yyyyMMddHHmm *.[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] # yyyyMMddHHmmss *.[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] # OS dependent files #--------------------------- .DS_Store Thumbs.db # Bundler specific #--------------------------- /vendor/bundle/ /.bundle/ # Office specific ~$* *.tmp # Vagrant specific .vagrant/ EOF --- ### ExcelからSnowflakeへSQLを実行するマクロボタンを作成する date: 2022-12-27 url: https://zatoima.github.io/snowflake-excel-sql-execute-macro-button/ tags: Snowflake ExcelからODBC経由でSQLを実行するマクロ 前回の記事で実施した接続初期設定 自体は完了しているという前提。 約10年振りのExcelマクロ。お試し用のメモです。M1 MacからSnowflakeへExcelで接続し、SQLを実行するマクロと実行ボタンを作成する QueryTableオブジェクトを使用するので、下記URLを参考に。 QueryTable オブジェクト (Excel) | Microsoft Learn Sub 更新() Dim uList As ListObject Dim uSQL As String Set uList = ActiveSheet.ListObjects("テーブル_ExternalData_1") 'ランダムに100行取得するSQLサンプルクエリ uSQL = "select * from testdb.public.LINEITEM_SMALL ORDER BY RANDOM() limit 100;" With uList.QueryTable .CommandText = uSQL .AdjustColumnWidth = True '列幅を調整する .Refresh BackgroundQuery:=False$$ End With End Sub データ表示ボタンを用意して、上記のスクリプトが実行されるように設定する。 実行時間の簡易計測 limitの数値を変えてから計測を実施。 対象テーブル定義 CREATE OR replace TABLE LINEITEM_SMALL AS SELECT * FROM SNOWFLAKE_SAMPLE_DATA.TPCH_SF100.LINEITEM LIMIT 100000000; 計測用のVBA Sub 更新() Dim start_time As Double Dim fin_time As Double start_time = Timer Dim uList As ListObject Dim uSQL As String '******************ここから処理を記入******************* Set uList = ActiveSheet.ListObjects("テーブル_ExternalData_1") uSQL = "select * from testdb.public.LINEITEM_SMALL ORDER BY RANDOM() limit 100000;" With uList.QueryTable .CommandText = uSQL .AdjustColumnWidth = False '列幅を調整する .Refresh BackgroundQuery:=False End With '******************ここまで******************* fin_time = Timer MsgBox "経過時間:" & fin_time - start_time End Sub 実行時間 取得件数 VBA実行時間 Query Profile 100 2.38 秒 1.7 秒 1,000 2.57 秒 1.8 秒 10,000 3.42 秒 2.2 秒 100,000 8.39 秒 5.4 秒 1,000,000 28.72 秒 20 秒 10,000,000 130.85 秒 119 秒 ※なお、Excelの最大行数が1,048,576のため、全行は表示出来ていない。 --- ### M1 MacからSnowflakeへExcelでODBC接続する date: 2022-12-26 url: https://zatoima.github.io/snowflake-m1-mac-excel-connect/ tags: Snowflake M1 MacからSnowflakeへExcelで接続する場合の設定メモ。 MacのVersion (base) jimazato@CJ2VQ9Y2M1 ~ % sw_vers ProductName: macOS ProductVersion: 13.0.1 BuildVersion: 22A400 ODBCとは Open Database Connectivity(オープン・データベース・コネクティビティ) https://e-words.jp/w/ODBC.html ODBCとは、アプリケーションソフトがデータベース管理システム(DBMS)などに接続し、データの取得や書き込み、操作などを行う方法の標準を定めたもの。Microsoft社が制定したもので、主に同社のWindowsで動作するデータベース関連ソフトウェアで用いられる。 なお、LinuxやUnix、Mac OSの場合はiODBCを使うことになる。 iODBCのダウンロード iODBC Driver Manager: iODBC Downloads arm64なので赤枠部分をダウンロードする。 ダウンロードしたiODBC-SDK-3.52.15-macOS11.dmgをインストール(インストーラーファイルのiODBC-SDK.pkgを実行していく) 下記ディレクトリにインストールされる。 (base) jimazato@CJ2VQ9Y2M1 ~ % cd "/Library/Application Support/iODBC/bin" (base) jimazato@CJ2VQ9Y2M1 bin % ls -l total 648 -rwxrwxr-x 1 root wheel 6222 6 7 2021 iodbc-config -rwxrwxr-x 1 root wheel 153360 6 7 2021 iodbctest -rwxrwxr-x 1 root wheel 153360 6 7 2021 iodbctestw -rwxrwxr-x 1 root wheel 9450 6 7 2021 uninstall-iodbc.pl ODBC マネージャーのインストール 下記からインストール http://www.odbcmanager.net/ Snowflake用のODBCドライバーのインストール Snowflake用のODBCドライバーをインストールする。 https://developers.snowflake.com/odbc/ macaarch64をインストール (base) jimazato@CJ2VQ9Y2M1 iODBC % cd /opt/snowflake/snowflakeodbc (base) jimazato@CJ2VQ9Y2M1 snowflakeodbc % ls -l total 0 drwxr-xr-x 3 root wheel 96 7 29 02:51 ErrorMessages drwxr-xr-x 4 root wheel 128 7 29 02:51 Setup drwxr-xr-x 3 root wheel 96 7 29 02:51 Tools drwxr-xr-x 3 root wheel 96 7 29 02:51 include drwxr-xr-x 3 root wheel 96 7 29 02:51 lib (base) jimazato@CJ2VQ9Y2M1 snowflakeodbc % find . . ./Tools ./Tools/DriverInstaller ./ErrorMessages ./ErrorMessages/en-US ./ErrorMessages/en-US/SQLEngineMessages.xml ./ErrorMessages/en-US/ODBCMessages.xml ./ErrorMessages/en-US/SFMessages.xml ./include ./include/sf_odbc.h ./Setup ./Setup/odbc.ini ./Setup/odbcinst.ini ./lib ./lib/universal ./lib/universal/libSnowflake.dylib ./lib/universal/cacert.pem ./lib/universal/simba.snowflake.ini (base) jimazato@CJ2VQ9Y2M1 snowflakeodbc % ODBC マネージャーを使用したデータソースの管理 ダウンロードした Snowflake ODBC ドライバーからすべてのファイルを /Library/ODBC/ODBCDataSources フォルダーにコピー (base) jimazato@CJ2VQ9Y2M1 ~ % cp /opt/snowflake/snowflakeodbc/lib/universal/* /Library/ODBC/ODBCDataSources (base) jimazato@CJ2VQ9Y2M1 ~ % (base) jimazato@CJ2VQ9Y2M1 ~ % cd /Library/ODBC/ODBCDataSources (base) jimazato@CJ2VQ9Y2M1 ODBCDataSources % ll total 281032 -rw-r--r--@ 1 jimazato admin 222172 12 23 21:21 cacert.pem -rwxr-xr-x@ 1 jimazato admin 143657808 12 23 21:21 libSnowflake.dylib -rw-r--r--@ 1 jimazato admin 1340 12 23 21:21 simba.snowflake.ini simba.snowflake.ini ファイルを開き、ODBCInstLibで ODBC ドライバー マネージャーのlibiodbcinst.dylibライブラリ パスを指定し、CABundleFile の詳細で証明書のcacert.pemパスを指定。 このとき、ODBCInstLibの場所に注意する必要がある。環境依存のケースが多いためmdfind -name libodbcinst.dylib等で検索した方が早そう。 vi /Library/ODBC/ODBCDataSources/simba.snowflake.ini # To use this INI file, replace [INSTALLDIR] with the # directory the tarball was extracted to. [Driver] ANSIENCODING=UTF-8 ## Note that this default DriverManagerEncoding of UTF-32 is for iODBC. unixODBC uses UTF-16 by default. ## If unixODBC was compiled with -DSQL_WCHART_CONVERT, then UTF-32 is the correct value. ## Execute 'odbc_config --cflags' to determine if you need UTF-32 or UTF-16 on unixODBC DriverManagerEncoding=UTF-32 DriverLocale=en-US ErrorMessagesPath=/Library/ODBC/ErrorMessages LogLevel=0 LogPath=/tmp CURLVerboseMode=false ODBCInstLib=/Users/jimaza$$to/opt/anaconda3/lib/libodbcinst.dylib CABundleFile=/Library/ODBC/ODBCDataSources/cacert.pem ## - Uncomment the ODBCInstLib corresponding to the Driver Manager being used. ## - Note that the path to your ODBC Driver Manager must be specified in LD_LIBRARY_PATH (LIBPATH for AIX, DYLD_LIBRARY_PATH for Darwin). ## - Note that AIX has a different format for specifying its shared libraries. # Generic ODBCInstLib # iODBC # ODBCInstLib=libiodbcinst.so # SimbaDM / unixODBC #ODBCInstLib=libodbcinst.so # Darwin specific ODBCInstLib # iODBC ODBCInstLib=libodbcinst.dylib # ODBCInstLib=libiodbcinst.dylib # AIX specific ODBCInstLib # iODBC #ODBCInstLib=libiodbcinst.a(libiodbcinst.so.2) # SimbaDM #ODBCInstLib=libodbcinst.a(odbcinst.so) # unixODBC #ODBCInstLib=libodbcinst.a(libodbcinst.so.1) odbcinst.iniの設定。このとき、変更するodbc.iniでユーザ個別の設定となるかのか全ユーザ共通の設定となるシステムDSNとなるかが決まる。下記の通り、このodbc.iniに異なるエントリを追加することで複数のDSN設定を持つことが出来る。 macOS用 ODBC ドライバーのインストールと構成 — Snowflake Documentation ユーザー DSNs : ~/Library/ODBC/odbc.ini システム DSNs : /Library/ODBC/odbc.ini (base) jimazato@CJ2VQ9Y2M1 ODBCDataSources % vi /Library/ODBC/odbcinst.ini (base) jimazato@CJ2VQ9Y2M1 ODBCDataSources % cat /Library/ODBC/odbcinst.ini [ODBC Drivers] SnowflakeDSIIDriver=Installed [SnowflakeDSIIDriver] APILevel=1 ConnectFunctions=YYY Description=Snowflake DSII Driver=/Library/ODBC/ODBCDataSources/libSnowflake.dylib DriverODBCVer=03.52 SQLLevel=1 odbc.iniの設定 (base) jimazato@CJ2VQ9Y2M1 ODBCDataSources % vi /Library/ODBC/odbc.ini (base) jimazato@CJ2VQ9Y2M1 ODBCDataSources % cat /Library/ODBC/odbc.ini$$ [ODBC Data Sources] SNOWFLAKE_ODBC_EXCEL = SnowflakeDSIIDriver [SNOWFLAKE_ODBC_EXCEL] Driver = /Library/ODBC/ODBCDataSources/libSnowflake.dylib Description = Internal Snowflake uid = zato server = xxxxx.ap-northeast-1.aws.snowflakecomputing.com database = testdb schema = public warehouse = WORK_WH role = WORKROLE tracing = 6 ここまでで事前準備が完了したので、ExcelからSnowflakeにODBC経由で接続する。 「データ」->「データベースから(Microsoft Query)」を選択 DSNを選択する画面が出力される。odbc.iniの内容が反映されているはずなのでSystem DSNから作成したDSNを選択する。 Testボタンをクリックするとユーザ名とパスワードを求められる。 正常に接続出来た場合、下記のように成功画面が出力される。 実際にクエリを設定する画面がこちら。SQLを直書きしてデータを引っ張ってくるSQLを定義する。 接続のプロパティとして下記のような設定画面がある。更新間隔やファイルを開くときにデータを更新する等が選択出来るが、都度都度ウェアハウスが起動してクエリが投げられるのもよろしくないと思うため、要件に応じて必要かどうか検討した方が良さそう。 クエリ文字列定義は定義タブで確認出来るため、SQLを修正したい場合はこちらから。 参考資料 How to configure Excel on MacOS to use Snowflake using ODBC driver? macOS用 ODBC ドライバーのインストールと構成 — Snowflake Documentation --- ### Anaconda環境にsnowflake-connector-pythonをインストール date: 2022-12-15 url: https://zatoima.github.io/snowflake-anaconda-snowflake-conector-python-install/ tags: Snowflake 参考URL: Snowflake Connector Python :: Anaconda.org conda-forge/snowflake-connector-python-feedstock: A conda-smithy repository for snowflake-connector-python. インストール pipであれば素直にpip install snowflake-connector-pythonで良いが、snowflake-connector-pythonがAnacondaのリポジトリにないのでconda-forgeを指定する必要あり。 conda install -c conda-forge snowflake-connector-python ハマったこと このときエラーでSolving environmentで先に進まなかったので下記記事を見てconda環境をアップデートした。 (base) jimazato@xxxxxxx AWS-Tokyo % conda install snowflake-connector-python Collecting package metadata (current_repodata.json): done Solving environment: failed with initial frozen solve. Retrying with flexible solve. Solving environment: failed with repodata from current_repodata.json, will retry with next repodata source. Collecting package metadata (repodata.json): / \ | \ conda updateで「Solving environment: failed」となった時の解決法 - Qiita conda install anaconda conda update --all --- ### 改行コードの確認方法 date: 2022-12-09 url: https://zatoima.github.io/tips-mac-newline-character-confirm/ tags: Tips 環境 xxxx@xxxx % sw_vers ProductName: macOS ProductVersion: 13.0.1 BuildVersion: 22A400 不要なBOM(byte order mark)や改行コードの確認のために使用出来る。 実行 xxxx@xxxx % od -c tpcds.sql 0000000 - - T P C - D S 0 1 \n w i t 0000020 h c u s t o m e r _ t o t a l 0000040 _ r e t u r n a s \n ( s e l e 0000060 c t s r _ c u s t o m e r _ s 0000100 k a s c t r _ c u s t o m e 0000120 r _ s k \n , s r _ s t o r e _ s 0000140 k a s c t r _ s t o r e _ s 0000160 k \n , s u m ( S R _ F E E ) a 0000200 s c t r _ t o t a l _ r e t u 0000220 r n \n f r o m s t o r e _ r e 0000240 t u r n s \n , d a t e _ d i m \n 0000260 w h e r e s r _ r e t u r n e 0000300 d _ d a t e _ s k = d _ d a 0000320 t e _ s k \n a n d d _ y e a r 0000340 = 2 0 0 0 \n g r o u p b y 0000360 s r _ c u s t o m e r _ s k \n , 0000400 s r _ s t o r e _ s k ) \n s e 0000420 l e c t c _ c u s t o m e r 0000440 _ i d \n f r o m c u s t o m e 0000460 r _ t o t a l _ r e t u r n c 0000500 t r 1 \n , s t o r e \n , c u s t 0000520 o m e r \n w h e r e c t r 1 . 0000540 c t r _ t o t a l _ r e t u r n 0000560 > ( s e l e c t a v g ( c 0000600 t r _ t o t a l _ r e t u r n ) 0000620 * 1 . 2 \n f r o m c u s t o m 0000640 e r _ t o t a l _ r e t u r n 0000660 c t r 2 \n w h e r e c t r 1 . 0000700 c t r _ s t o r e _ s k = c 0000720 t r 2 . c t r _ s t o r e _ s k 0000740 ) \n a n d s _ s t o r e _ s k 0000760 = c t r 1 . c t r _ s t o r 0001000 e _ s k \n a n d s _ s t a t e 0001020 = ' N M ' \n a n d c t r 1 0001040 . c t r _ c u s t o m e r _ s k 0001060 = c _ c u s t o m e r _ s k 0001100 \n o r d e r b y c _ c u s t 0001120 o m e r _ i d \n l i m i t 1 0 0001140 0 ; \n \n 0001144 --- ### Github Pages Hugoの新端末でのセットアップメモ date: 2022-12-06 url: https://zatoima.github.io/hugo-github-pages-setup-memo/ tags: Hugo WindowsからMacにHugoのブログ執筆環境を移行した際の環境構築(移行)メモです。 OS確認 xxxx@xxxx blog % sw_vers ProductName: macOS ProductVersion: 13.0.1 BuildVersion: 22A400 hugoのインストール brew install hugo 作業用ディレクトリの作成 mkdir -p /Users/jimazato/work/hugo/zatoima.github.io Githubの初期設定 公開鍵を生成してGithubのSSH and GPG Keysに登録する cd $HOME/.ssh && ls ssh-keygen -t rsa -f id_rsa_git cat id_rsa_git.pub ssh接続の際「~/.ssh/id_rsa」、「~/.ssh/id_dsa」、「~/.ssh/identity」しかデフォルトではチェックしないので、デフォルトから変更した場合は$HOME/.ssh配下にconfigファイルを作成し下記のように記載する。 jimazato@XXXXXXX .ssh % cat config Host github github.com HostName github.com IdentityFile ~/.ssh/id_rsa_git #ここに自分の鍵のファイル名 User git これをやっていない場合、pushやpull時に下記のようにエラーとなってしまう。 jimazato@XXXXXXX zatoima.github.io % git pull origin master This key is not known by any other names Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added 'github.com' (ED25519) to the list of known hosts. git@github.com: Permission denied (publickey). fatal: Could not read from remote repository. その他のGithub側の初期設定。 git config --global user.name zatoima git config --global user.email xxxx.xxxxx@gmail.com git remote set-url origin git@github.com: git remote set-url origin git@github.com:zatoima/zatoima.github.io.git こんな感じになっていると思う jimazato@XXXXXXX zatoima.github.io % git remote -v origin git@github.com:zatoima/zatoima.git (fetch) origin git@github.com:zatoima/zatoima.git (push) ここまで来たらpullやpush、clone等をして設定の正しさを確認する。 --- ### AWS IAMポリシーのCondition句のStringEqualsに複数条件を記載する date: 2022-12-05 url: https://zatoima.github.io/aws-iam-policy-condition-multipul/ tags: AWS 参考 IAM JSON ポリシー要素: Condition - AWS Identity and Access Management OR条件となるIAMポリシー { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::xxxxxxx:user/xxxx-s" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "sts:ExternalId": ["xxxxxxx_SFCRole=2_JVxxxxxxO3Bd/Pr0=","xxxxxxx_SFCRole=2_dxxxxxxiw="] } } } ] } NGパターン そもそも構文としてNG { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::xxxxxxx:user/xxxx-s" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "sts:ExternalId": "xxxxxxx_SFCRole=2_JVxxxxxxO3Bd/Pr0=", "sts:ExternalId": "xxxxxxx_SFCRole=2_dxxxxxxiw=" } } } ] } 冗長なのでNG { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::xxxxxxx:user/xxxx-s" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "sts:ExternalId": "xxxxxxx_SFCRole=2_JVxxxxxxO3Bd/Pr0=" } } }, { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::xxxxxxx:user/bkm20000-s" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "sts:ExternalId": "xxxxxxx_SFCRole=2_dxxxxxxiw=" } } } ] } --- ### 本ブログへのアクセス数メモ 2022年10月 date: 2022-11-13 url: https://zatoima.github.io/hugo-access-number-memo/ tags: Hugo 久しぶりにGoogle Analyticsを確認してみた。下記はGAをソースにしてGoogle Spreadsheet でグラフ化。2019年12月にはてなからGithub Pagesに移行した後のデータとなる。メモ代わりのGithub Pages運用がここまでアクセス数が多いとは。平日は700-800PVでセッション数だと1000を超える日もある。HugoのSEOが強いのか、更新頻度が高いからなのか、Github Pagesが強いのか。Githubドメインが強いのか…。 --- ### Snowflake向けのTPC-HベンチマークをPythonから実行する date: 2022-11-12 url: https://zatoima.github.io/snowflake-python-tpc-h-execute/ tags: snowflake このGithubのスクリプトを参考にしつつ動くようにしました。 参考資料 TPC BENCHMARKTM H https://www.tpc.org/tpc_documents_current_versions/pdf/tpc-h_v3.0.1.pdf TPC Download Current Specs/Source https://www.tpc.org/tpc_documents_current_versions/current_specifications5.asp?utm_source=pocket_saves 事前準備 スクリプト実行環境 zatoima@M1MBA snowflake_benchmark % sw_vers ProductName: macOS ProductVersion: 13.0 BuildVersion: 22A380 ロール作成するためにSECURITYADMINを使用 USE ROLE SECURITYADMIN; ロール作成 CREATE ROLE WORKROLE; 作ったSYSADMIN および自分のユーザーに権限を付与する(継承) GRANT ROLE WORKROLE TO ROLE SYSADMIN; GRANT ROLE WORKROLE TO USER zato; ウェアハウスを作るのでロール切り替え&作成 USE ROLE SYSADMIN; CREATE WAREHOUSE WORK_WH WITH WAREHOUSE_SIZE = xsmall INITIALLY_SUSPENDED = TRUE AUTO_SUSPEND = 60 AUTO_RESUME = TRUE; ウェアハウスの使用権限の付与 GRANT USAGE ON WAREHOUSE WORK_WH TO ROLE WORKROLE; DB作成 CREATE DATABASE TESTDB; 任意のスキーマでテーブルを作成するために必要なすべての権限をロールに付与 GRANT USAGE ON DATABASE TESTDB TO ROLE WORKROLE; GRANT USAGE ON SCHEMA TESTDB.PUBLIC TO ROLE WORKROLE; GRANT CREATE TABLE ON SCHEMA TESTDB.PUBLIC TO ROLE WORKROLE; テーブル作成 USE ROLE WORKROLE; USE WAREHOUSE WORK_WH; USE DATABASE TESTDB; USE SCHEMA TESTDB.PUBLIC; VIEW作成用のスキーマを作成 CREATE DATABASE TESTDB; CREATE SCHEMA temp; GRANT USAGE ON DATABASE TESTDB TO ROLE WORKROLE; GRANT USAGE ON SCHEMA TESTDB.temp TO ROLE WORKROLE; GRANT CREATE TABLE ON SCHEMA TESTDB.temp TO ROLE WORKROLE; GRANT CREATE VIEW ON SCHEMA TESTDB.TEMP TO ROLE WORKROLE; pipでライブラリをインストール pip install snowflake.connector,logzero 下記の通りファイルを配置する zatoima@M1MBA snowflake_benchmark % tree . ├── tpch.py └── tpch.sql Python tpch.pyとして作成。環境依存部分を書き換える。結果キャッシュを使わないようにセッションパラメータ(USE_CACHED_RESULT)を設定。 import snowflake.connector import time from logzero import logger import logzero import os # 環境依存 direct_con = snowflake.connector.connect( user='xxxx', password='xxxxx', account='xxxxxxx', database='SNOWFLAKE_SAMPLE_DATA', schema='tpch_sf10', warehouse='WORK_WH' session_parameters={ 'USE_CACHED_RESULT': 'False', } ) NUM_OF_SAMPLES = 10 # 環境依存ここまで # SQLスクリプト側のVIEWの作成用データベースとスキーマも環境依存なので注意 def benchmark(): print("Benchmarking for snowflake") filename = "results.txt" with open(filename, 'w') as result_file: with open('tpch.sql') as f: all_queries = f.read() results = "Test\tTime\n" for i in range(0, NUM_OF_SAMPLES): # Running the benchmark for each query in the queries file for query in all_queries.split(';'): #If there is a blank line, "IndexError: list index out of range list split" is returned, so "if statement" is added. if query != '\n': label = query.split("-- ")[1].split('\n')[0] query = query.rstrip() start_ts = time.time() logger.info(label + " Start!!") cs = direct_con.cursor() cs.execute(query) rows = cs.fetchall() for _row in rows: continue end_ts = time.time() delta = end_ts-start_ts # Results are tab-delimited for easy pasting to a spreadsheet results += "{0:s}\t{1:3.5f}\n".format(label, delta) logger.info(label + " Done!!") result_file.write(results) if __name__ == "__main__": if "LOG_LEVEL" in os.environ: logzero.loglevel(int(os.environ["LOG_LEVEL"])) benchmark() 実行用SQL Python側から呼ばれるTPC-H用のSQL。 ※VIEWの作成用データベースとスキーマも環境依存なので注意。TESTDBのTEMPスキーマに作成している -- TPC-H 1 select l_returnflag, l_linestatus, sum(l_quantity) as sum_qty, sum(l_extendedprice) as sum_base_price, sum(l_extendedprice * (1 - l_discount)) as sum_disc_price, sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge, avg(l_quantity) as avg_qty, avg(l_extendedprice) as avg_price, avg(l_discount) as avg_disc, count(*) as count_order from lineitem where l_shipdate <= DATEADD(day, 90, '1998-12-01') group by l_returnflag, l_linestatus order by l_returnflag, l_linestatus; -- TPC-H 2 select s_acctbal, s_name, n_name, p_partkey, p_mfgr, s_address, s_phone, s_comment from part, supplier, partsupp, nation, region where p_partkey = ps_partkey and s_suppkey = ps_suppkey and p_size = 15 and p_type like '%BRASS' and s_nationkey = n_nationkey and n_regionkey = r_regionkey and r_name = 'EUROPE' and ps_supplycost = ( select min(ps_supplycost) from partsupp, supplier, nation, region where p_partkey = ps_partkey and s_suppkey = ps_suppkey and s_nationkey = n_nationkey and n_regionkey = r_regionkey and r_name = 'EUROPE' ) order by s_acctbal desc, n_name, s_name, p_partkey LIMIT 100; -- TPC-H 3 select l_orderkey, sum(l_extendedprice * (1 - l_discount)) as revenue, o_orderdate, o_shippriority from customer, orders, lineitem where c_mktsegment = 'BUILDING' and c_custkey = o_custkey and l_orderkey = o_orderkey and o_orderdate < date '1995-03-15' and l_shipdate > date '1995-03-15' group by l_orderkey, o_orderdate, o_shippriority order by revenue desc, o_orderdate limit 10; -- TPC-H 4 select o_orderpriority, count(*) as order_count from orders where o_orderdate >= date '1993-07-01' AND o_orderdate < DATEADD(month, 3, '1993-07-01') and exists ( select * from lineitem where l_orderkey = o_orderkey and l_commitdate < l_receiptdate ) group by o_orderpriority order by o_orderpriority; -- TPC-H 5 select n_name, sum(l_extendedprice * (1 - l_discount)) as revenue from customer, orders, lineitem, supplier, nation, region where c_custkey = o_custkey and l_orderkey = o_orderkey and l_suppkey = s_suppkey and c_nationkey = s_nationkey and s_nationkey = n_nationkey and n_regionkey = r_regionkey and r_name = 'ASIA' and o_orderdate >= date '1994-01-01' AND o_orderdate < DATEADD(year, 1, '1994-01-01') group by n_name order by revenue desc; -- TPC-H 6 select sum(l_extendedprice * l_discount) as revenue from snowflake_sample_data.tpch_sf1.lineitem where l_shipdate >= date '1994-01-01' AND l_shipdate < DATEADD(year, 1, '1994-01-01') and l_discount between .06 - 0.01 and .06 + 0.01 and l_quantity < 24; -- TPC-H 7 select supp_nation, cust_nation, l_year, sum(volume) as revenue from ( select n1.n_name as supp_nation, n2.n_name as cust_nation, extract(year from l_shipdate) as l_year, l_extendedprice * (1 - l_discount) as volume from supplier, lineitem, orders, customer, nation n1, nation n2 where s_suppkey = l_suppkey and o_orderkey = l_orderkey and c_custkey = o_custkey and s_nationkey = n1.n_nationkey and c_nationkey = n2.n_nationkey and ( (n1.n_name = 'FRANCE' and n2.n_name = 'GERMANY') or (n1.n_name = 'GERMANY' and n2.n_name = 'FRANCE') ) and l_shipdate between date '1995-01-01' and date '1996-12-31' ) as shipping group by supp_nation, cust_nation, l_year order by supp_nation, cust_nation, l_year; -- TPC-H 8 select o_year, sum(case when nation = 'BRAZIL' then volume else 0 end) / sum(volume) as mkt_share from ( select extract(year from o_orderdate) as o_year, l_extendedprice * (1 - l_discount) as volume, n2.n_name as nation from part, supplier, lineitem, orders, customer, nation n1, nation n2, region where p_partkey = l_partkey and s_suppkey = l_suppkey and l_orderkey = o_orderkey and o_custkey = c_custkey and c_nationkey = n1.n_nationkey and n1.n_regionkey = r_regionkey and r_name = 'AMERICA' and s_nationkey = n2.n_nationkey and o_orderdate between date '1995-01-01' and date '1996-12-31' and p_type = 'ECONOMY ANODIZED STEEL' ) as all_nations group by o_year order by o_year; -- TPC-H 9 select nation, o_year, sum(amount) as sum_profit from ( select n_name as nation, extract(year from o_orderdate) as o_year, l_extendedprice * (1 - l_discount) - ps_supplycost * l_quantity as amount from part, supplier, lineitem, partsupp, orders, nation where s_suppkey = l_suppkey and ps_suppkey = l_suppkey and ps_partkey = l_partkey and p_partkey = l_partkey and o_orderkey = l_orderkey and s_nationkey = n_nationkey and p_name like '%green%' ) as profit group by nation, o_year order by nation, o_year desc; -- TPC-H 10 select c_custkey, c_name, sum(l_extendedprice * (1 - l_discount)) as revenue, c_acctbal, n_name, c_address, c_phone, c_comment from customer, orders, lineitem, nation where c_custkey = o_custkey and l_orderkey = o_orderkey and o_orderdate >= date '1993-10-01' AND o_orderdate < DATEADD(month, 3, '1993-10-01') and l_returnflag = 'R' and c_nationkey = n_nationkey group by c_custkey, c_name, c_acctbal, c_phone, n_name, c_address, c_comment order by revenue desc limit 20; -- TPC-H 11 select ps_partkey, sum(ps_supplycost * ps_availqty) as value from partsupp, supplier, nation where ps_suppkey = s_suppkey and s_nationkey = n_nationkey and n_name = 'GERMANY' group by ps_partkey having sum(ps_supplycost * ps_availqty) > ( select sum(ps_supplycost * ps_availqty) * 0.0001000000 from partsupp, supplier, nation where ps_suppkey = s_suppkey and s_nationkey = n_nationkey and n_name = 'GERMANY' ) order by value desc; -- TPC-H 12 select l_shipmode, sum(case when o_orderpriority = '1-URGENT' or o_orderpriority = '2-HIGH' then 1 else 0 end) as high_line_count, sum(case when o_orderpriority <> '1-URGENT' and o_orderpriority <> '2-HIGH' then 1 else 0 end) as low_line_count from orders, lineitem where o_orderkey = l_orderkey and l_shipmode in ('MAIL', 'SHIP') and l_commitdate < l_receiptdate and l_shipdate < l_commitdate and l_receiptdate >= date '1994-01-01' AND o_orderdate < DATEADD(year, 1, '1994-01-01') group by l_shipmode order by l_shipmode; -- TPC-H 13 select c_count, count(*) as custdist from ( select c_custkey, count(o_orderkey) from customer left outer join orders on c_custkey = o_custkey and o_comment not like '%special%requests%' group by c_custkey ) as c_orders (c_custkey, c_count) group by c_count order by custdist desc, c_count desc; -- TPC-H 14 select 100.00 * sum(case when p_type like 'PROMO%' then l_extendedprice * (1 - l_discount) else 0 end) / sum(l_extendedprice * (1 - l_discount)) as promo_revenue from lineitem, part where l_partkey = p_partkey and l_shipdate >= date '1995-09-01' AND l_shipdate < DATEADD(month, 1, '1995-09-01'); -- TPC-H 15-create create view testdb.temp.revenue0 (supplier_no, total_revenue) as select l_suppkey, sum(l_extendedprice * (1 - l_discount)) from snowflake_sample_data.tpch_sf1.lineitem where l_shipdate >= date '1996-01-01' AND l_shipdate < DATEADD(month, 3, '1996-01-01') group by l_suppkey; -- TPC-H 15 select s_suppkey, s_name, s_address, s_phone, total_revenue from supplier, testdb.temp.revenue0 where s_suppkey = supplier_no and total_revenue = ( select max(total_revenue) from testdb.temp.revenue0 ) order by s_suppkey; -- TPC-H 15-drop drop view testdb.temp.revenue0; -- TPC-H 16 select p_brand, p_type, p_size, count(distinct ps_suppkey) as supplier_cnt from partsupp, part where p_partkey = ps_partkey and p_brand <> 'Brand#45' and p_type not like 'MEDIUM POLISHED%' and p_size in (49, 14, 23, 45, 19, 3, 36, 9) and ps_suppkey not in ( select s_suppkey from supplier where s_comment like '%Customer%Complaints%' ) group by p_brand, p_type, p_size order by supplier_cnt desc, p_brand, p_type, p_size; -- TPC-H 17 select sum(l_extendedprice) / 7.0 as avg_yearly from lineitem, part where p_partkey = l_partkey and p_brand = 'Brand#23' and p_container = 'MED BOX' and l_quantity < ( select 0.2 * avg(l_quantity) from lineitem where l_partkey = p_partkey ); -- TPC-H 18 select c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice, sum(l_quantity) from customer, orders, lineitem where o_orderkey in ( select l_orderkey from lineitem group by l_orderkey having sum(l_quantity) > 300 ) and c_custkey = o_custkey and o_orderkey = l_orderkey group by c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice order by o_totalprice desc, o_orderdate limit 100; -- TPC-H 19 select sum(l_extendedprice* (1 - l_discount)) as revenue from lineitem, part where ( p_partkey = l_partkey and p_brand = 'Brand#12' and p_container in ('SM CASE', 'SM BOX', 'SM PACK', 'SM PKG') and l_quantity >= 1 and l_quantity <= 1 + 10 and p_size between 1 and 5 and l_shipmode in ('AIR', 'AIR REG') and l_shipinstruct = 'DELIVER IN PERSON' ) or ( p_partkey = l_partkey and p_brand = 'Brand#23' and p_container in ('MED BAG', 'MED BOX', 'MED PKG', 'MED PACK') and l_quantity >= 10 and l_quantity <= 10 + 10 and p_size between 1 and 10 and l_shipmode in ('AIR', 'AIR REG') and l_shipinstruct = 'DELIVER IN PERSON' ) or ( p_partkey = l_partkey and p_brand = 'Brand#34' and p_container in ('LG CASE', 'LG BOX', 'LG PACK', 'LG PKG') and l_quantity >= 20 and l_quantity <= 20 + 10 and p_size between 1 and 15 and l_shipmode in ('AIR', 'AIR REG') and l_shipinstruct = 'DELIVER IN PERSON' ); -- TPC-H 20 select s_name, s_address from supplier, nation where s_suppkey in ( select ps_suppkey from partsupp where ps_partkey in ( select p_partkey from part where p_name like 'forest%' ) and ps_availqty > ( select 0.5 * sum(l_quantity) from lineitem where l_partkey = ps_partkey and l_suppkey = ps_suppkey and l_shipdate >= date '1994-01-01' AND l_shipdate < DATEADD(year, 1, '1994-01-01') ) ) and s_nationkey = n_nationkey and n_name = 'CANADA' order by s_name; -- TPC-H 21 select s_name, count(*) as numwait from supplier, lineitem l1, orders, nation where s_suppkey = l1.l_suppkey and o_orderkey = l1.l_orderkey and o_orderstatus = 'F' and l1.l_receiptdate > l1.l_commitdate and exists ( select * from lineitem l2 where l2.l_orderkey = l1.l_orderkey and l2.l_suppkey <> l1.l_suppkey ) and not exists ( select * from lineitem l3 where l3.l_orderkey = l1.l_orderkey and l3.l_suppkey <> l1.l_suppkey and l3.l_receiptdate > l3.l_commitdate ) and s_nationkey = n_nationkey and n_name = 'SAUDI ARABIA' group by s_name order by numwait desc, s_name limit 100; -- TPC-H 22 select cntrycode, count(*) as numcust, sum(c_acctbal) as totacctbal from ( select SUBSTRING(c_phone, 1, 2) AS cntrycode, c_acctbal from customer where SUBSTRING(c_phone, 1, 2) IN ('13', '31', '23', '29', '30', '18', '17') and c_acctbal > ( select avg(c_acctbal) from customer where c_acctbal > 0.00 AND SUBSTRING(c_phone, 1, 2) IN ('13', '31', '23', '29', '30', '18', '17') ) and not exists ( select * from orders where o_custkey = c_custkey ) ) as custsale group by cntrycode order by cntrycode 実行 python3 tpch.py 実行後 results.txtに出力される zatoima@M1MBA snowflake_benchmark % cat results.txt Test Time TPC-H 1 113.73667 TPC-H 2 99.42642 TPC-H 3 75.91233 TPC-H 4 90.76858 TPC-H 5 106.15041 TPC-H 6 0.61596 TPC-H 7 101.50721 TPC-H 8 72.16892 TPC-H 9 153.48268 TPC-H 10 180.15991 TPC-H 11 87.48690 TPC-H 12 64.69897 TPC-H 13 435.00685 TPC-H 14 5.21159 TPC-H 15-create 0.27758 TPC-H 15 1.82527 TPC-H 15-drop 0.17074 TPC-H 16 78.74033 TPC-H 17 25.61653 TPC-H 18 122.15002 TPC-H 19 19.55574 TPC-H 20 28.58548 TPC-H 21 78.01457 TPC-H 22 9.47315 バッググランド実行をしてキューの溜まり具合やマルチクラスタの動作を見ることができるはず。どうせならウェアハウスのサイズ変更の自動化を出来るようにしておけばよかった。 --- ### Hugoの記事一覧の取得 date: 2022-11-08 url: https://zatoima.github.io/blog-hugo-article-list/ tags: blog BeautifulSoupを使ってHugoの記事一覧を取得する import requests from bs4 import BeautifulSoup import time def load_page(url): html = requests.get(url) soup = BeautifulSoup(html.content, 'html.parser') return soup #1ページ目はpage数を指定してアクセス出来ない #1ページ目 url='https://zatoima.github.io/post/' soup = load_page(url.format(url)) title_ = soup.find_all(class_='section-subheading article-title mb-0 mt-0') for title_text in title_: print(title_text.text.strip()) #2ページ以降 max_page = 100 url = 'https://zatoima.github.io/post/page/{}' for page in range(2,max_page+1): soup = load_page(url.format(page)) title_ = soup.find_all(class_='section-subheading article-title mb-0 mt-0') for title_text in title_: print(title_text.text.strip()) Post一覧画面 実行 --- ### EC2(Amazon Linux)にDockerをインストール date: 2022-10-31 url: https://zatoima.github.io/aws-ec2-docker-amazon-linux-install/ tags: AWS EC2作成時にユーザデータにぶっこむか、もしくは起動後に手動実行 #!/bin/bash sudo yum update -y sudo amazon-linux-extras install docker sudo systemctl start docker sudo systemctl enable docker sudo usermod -a -G docker ec2-user 動作確認用 docker -v docker run hello-world --- ### Pythonのpandas-datareaderで取得できる代表的なデータをまとめる date: 2022-10-24 url: https://zatoima.github.io/python-pandas-datareader-data-from-fred/ tags: Python 各種経済指標はここから取得ができる。代表的なものを抜き出す。 Categories of Economic Data | FRED | St. Louis Fed import pandas as pd import datetime as dt import pandas_datareader.data as pdr start = dt.date(2006,1,1) stop = dt.date(2022,1,1) SYMBOLS=['DJIA','SP500','NIKKEI225','NASDAQ100','DGS10','GS10','T10Y3M','T10Y2Y','DFEDTARU','DFEDTARL','DFF','IRLTLT01JPM156N','PAYEMS','UNRATE','LRUN64TTJPM156S','A191RL1Q225SBEA','GDP','GDPC1','CPALTT01USM659N','ICSA','IPUTIL','JPNNGDP','EXPJP','IMPJP','XTEXVA01JPM667S','XTIMVA01JPM667S','DEXJPUS','DEXCHUS','DEXUSEU','DEXINUS'] df = pdr.DataReader(SYMBOLS, 'fred', start, stop) import matplotlib.pyplot as plt %matplotlib inline plt.plot(df.index, df['EXPJP'],label='EXPJP') plt.plot(df.index, df['IMPJP'],label='IMPJP') plt.legend() plt.show() --- ### DMM英会話の受講履歴をCalendar Heatmapで可視化 date: 2022-10-19 url: https://zatoima.github.io/python-dmm-online-eikaiwa-calendar-heatmap/ tags: Python DMM英会話の受講履歴をCalendar Heatmapで可視化するやつをPythonでなんとか作った。Pythonの実務経験ゼロなのでお作法や効率などはどこかに置いています。 スクレイピング部分はこちらのコードを参考にして流用させていただきました。 kempei/mfstockupdater: Stock price updater for MoneyForward using Selenium スクレイピングはサイト側の規約と負荷に十分に注意しましょう。 スクレイピング前準備 from logzero import logger import logzero import chromedriver_binary import selenium from selenium import webdriver from selenium.webdriver.support.ui import Select from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as ec import requests import os, time, datetime import imaplib, email, re logger.info("selenium initializing...") options = webdriver.ChromeOptions() #options.add_argument("--headless") options.add_argument("--disable-gpu") options.add_argument("--window-size=800x900") options.add_argument("--disable-application-cache") options.add_argument("--disable-infobars") options.add_argument("--no-sandbox") options.add_argument("--hide-scrollbars") options.add_argument("--v=99") options.add_argument("--ignore-certificate-errors") options.add_argument("--homedir=/tmp") options.add_argument('--user-agent=Mozilla/5.0') options.add_argument('--disable-dev-shm-usage') options.add_experimental_option("prefs", {'profile.managed_default_content_settings.images':2}) driver = webdriver.Chrome(options=options) wait = WebDriverWait(driver, 5) driver.implicitly_wait(10) 関数定義 def send_to_element(xpath, keys): element = driver.find_element(by=By.XPATH, value=xpath) element.clear() logger.debug("[send_to_element] " + xpath) element.send_keys(keys) def send_to_element_direct(element, keys): element.clear() logger.debug("[send_to_element] " + element.get_attribute('id')) element.send_keys(keys) スクレイピング 事前に環境変数を定義しておく。 export DMM_ID=xxxxx export DMM_PASS=xxxx driver.execute_script("window.open()") if not 'DMM_ID' in os.environ or not 'DMM_PASS' in os.environ: raise ValueError("env DMM_ID and/or DMM_PASS are not found.") DMM_ID = os.environ['DMM_ID'] DMM_PASS = os.environ['DMM_PASS'] driver.get('https://accounts.dmm.com/service/login/password/') wait.until(ec.presence_of_all_elements_located) driver.find_element(by=By.XPATH, value='//input[@name="login_id"]').click() wait.until(ec.presence_of_all_elements_located) time.sleep(3) send_to_element('//input[@type="text"]', DMM_ID) driver.find_element(by=By.XPATH, value='//input[@type="password"]').click() wait.until(ec.presence_of_all_elements_located) time.sleep(3) send_to_element('//input[@type="password"]', DMM_PASS) driver.find_element(by=By.XPATH, value='//input[@data-e2e="login_button"]').click() wait.until(ec.presence_of_all_elements_located) time.sleep(3) if driver.find_element(by=By.XPATH, value='//input[@name="searchstr"]'): logger.info("successfully logged in.") レッスン受講履歴の取得 start_yearとend_yearが可変部分。ページ数を取得して必要な分だけループが効率的だと思うが諦め import datetime dt_now = datetime.datetime.now() #必要に応じて変更する start_year=2022 end_year=2023 target_month=[] for y in range(start_year,end_year): for m in range(1,13): aa='{}{}'.format(y,m) aa=datetime.datetime.strptime(aa, '%Y%m') if aa > dt_now: break aa=aa.strftime('%Y%m') target_month.append(aa) logger.info("target_month : "+str(target_month)) resson_date=[] for m in target_month: for i in range(1,5): url='https://eikaiwa.dmm.com/lesson/index/{}/?hd={}/' url=url.format(i,m) driver.get(url) if driver.find_elements(by=By.XPATH, value='//header[@id="time"]'): resson_times = driver.find_elements(by=By.XPATH, value='//header[@id="time"]') for r in resson_times: r=r.text.strip('レッスンノート').strip().partition('(')[0] r=datetime.datetime.strptime(r, '%Y年%m月%d日') r=r.strftime('%Y/%m/%d') resson_date.append(r) time.sleep(1) logger.info("resson_date : "+str(resson_date)) calplotでcalendar heatmapを作成 import calplot import numpy as np; np.random.seed(sum(map(ord, 'calplot'))) import pandas as pd df_calmap = pd.DataFrame({'Date':resson_date}) df_calmap['Count'] = 1 df_calmap=df_calmap.drop_duplicates() all_days = pd.date_range('1/1/2022', periods=600, freq='D') days = pd.to_datetime(df_calmap['Date']).to_list() e=df_calmap['Count'].to_list() #print(days) events = pd.Series(e, index=days) calplot.calplot(events, cmap='YlGn', colorbar=True, edgecolor=None) --- ### PostgreSQLで月初、月末日、翌月月初を取得する date: 2022-10-15 url: https://zatoima.github.io/postgresql-sql-month_first/ tags: PostgreSQL, SQL メモ。 select date(date_trunc('month',current_date)); -- 月初 select date(date_trunc('month',current_date) + ' 1 month' + '-1 Day'); -- 月末日 select date(date_trunc('month',current_date) + ' 1 month'); -- 翌月の月初 postgres=# select date(date_trunc('month',current_date)); -- 月初 date ------------ 2022-10-01 (1 row) postgres=# select date(date_trunc('month',current_date) + ' 1 month' + '-1 Day'); -- 月末日 date ------------ 2022-10-31 (1 row) postgres=# select date(date_trunc('month',current_date) + ' 1 month'); -- 翌月の月初 date ------------ 2022-11-01 (1 row) --- ### OCI上のOracle Linux8にDockerをインストールする date: 2022-10-13 url: https://zatoima.github.io/ici-oracle-linux-8-docker-install/ tags: OCI Docker Docker20.10くらいからRHEL8系でもDockerが使えるようになったが、デフォのリポジトリ設定だとRedhatのpodman-dockerをインストールしようとしてくるのでどうにかDockerをメモ。 環境設定 [opc@oci-arm ~]$ cat /etc/redhat-release Red Hat Enterprise Linux release 8.6 (Ootpa) [opc@oci-arm ~]$ cat /etc/oracle-release Oracle Linux Server release 8.6 [opc@oci-arm ~]$ cat /etc/os-release NAME="Oracle Linux Server" VERSION="8.6" ID="ol" ID_LIKE="fedora" VARIANT="Server" VARIANT_ID="server" VERSION_ID="8.6" PLATFORM_ID="platform:el8" PRETTY_NAME="Oracle Linux Server 8.6" ANSI_COLOR="0;31" CPE_NAME="cpe:/o:oracle:linux:8:6:server" HOME_URL="https://linux.oracle.com/" BUG_REPORT_URL="https://bugzilla.oracle.com/" ORACLE_BUGZILLA_PRODUCT="Oracle Linux 8" ORACLE_BUGZILLA_PRODUCT_VERSION=8.6 ORACLE_SUPPORT_PRODUCT="Oracle Linux" ORACLE_SUPPORT_PRODUCT_VERSION=8.6 レポジトリ設定 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo [opc@oci-arm ~]$ sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo Adding repo from: https://download.docker.com/linux/centos/docker-ce.repo インストール sudo dnf install -y docker-ce docker-ce-cli containerd.io [opc@oci-arm ~]$ sudo dnf install -y docker-ce docker-ce-cli containerd.io Docker CE Stable - aarch64 431 kB/s | 26 kB 00:00 Dependencies resolved. 〜省略〜 Installed: container-selinux-2:2.188.0-1.module+el8.6.0+20721+d8d917a9.noarch containerd.io-1.6.8-3.1.el8.aarch64 docker-ce-3:20.10.18-3.el8.aarch64 docker-ce-cli-1:20.10.18-3.el8.aarch64 docker-ce-rootless-extras-20.10.18-3.el8.aarch64 fuse-common-3.3.0-15.0.2.el8.aarch64 fuse-overlayfs-1.9-1.module+el8.6.0+20721+d8d917a9.aarch64 fuse3-3.3.0-15.0.2.el8.aarch64 fuse3-libs-3.3.0-15.0.2.el8.aarch64 libcgroup-0.41-19.el8.aarch64 libslirp-4.4.0-1.module+el8.6.0+20721+d8d917a9.aarch64 slirp4netns-1.2.0-2.module+el8.6.0+20721+d8d917a9.aarch64 Complete インストール後作業 sudo gpasswd -a $(whoami) docker sudo chgrp docker /var/run/docker.sock これを実施しないと権限エラーとなる。 [opc@oci-arm cli-plugins]$ docker ps Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get “http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json": dial unix /var/run/docker.sock: connect: permission denied バージョン確認 [opc@oci-arm ~]$ docker -v Docker version 20.10.18, build b40c2f6 [opc@oci-arm ~]$ docker version Client: Docker Engine - Community Version: 20.10.18 API version: 1.41 Go version: go1.18.6 Git commit: b40c2f6 Built: Thu Sep 8 23:10:56 2022 OS/Arch: linux/arm64 Context: default Experimental: true Server: Docker Engine - Community Engine: Version: 20.10.18 API version: 1.41 (minimum version 1.12) Go version: go1.18.6 Git commit: e42327a Built: Thu Sep 8 23:09:25 2022 OS/Arch: linux/arm64 Experimental: false containerd: Version: 1.6.8 GitCommit: 9cd3357b7fd7218e4aec3eae239db1f68a5a6ec6 runc: Version: 1.1.4 GitCommit: v1.1.4-0-g5fd4c4d docker-init: Version: 0.19.0 GitCommit: de40ad0 Dockerの起動 sudo systemctl start docker Dockerの自動起動設定 sudo systemctl enable docker docker-compose Docker Compose CLI プラグインのインストール — Docker-docs-ja 20.10 ドキュメント この環境はarmなのでaarch64のバイナリを取得しているが、intel系の場合はここを別に変える必要あり。 curl -SL https://github.com/docker/compose/releases/download/v2.11.2/docker-compose-linux-aarch64 -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose pc@oci-arm cli-plugins]$ docker-compose -v Docker Compose version v2.11.2 --- ### SnowflakeでS3の外部テーブルでクエリする date: 2022-10-12 url: https://zatoima.github.io/snowflake-s3-external-table-query/ tags: snowflake 概要 S3上に配置したParquetやCSV等のファイルをクエリすることができる Redshift Spectrumみたいな機能と理解 注意事項 「VALUE」というカラムにJSONオブジェクト形式でファイルの値が格納される データベースの外部に保存されているデータのクエリは、ネイティブデータベーステーブルのクエリよりも遅い可能性がある(とマニュアルには記載があった) データベースの外部に保存されているデータのクエリは、ネイティブデータベーステーブルのクエリよりも遅い可能性があります。 https://docs.snowflake.com/ja/user-guide/tables-external-intro.html パフォーマンスを上げたい場合にはマテリアライズドビューと組み合わせる 外部テーブルのマテリアライズドビュー — Snowflake Documentation パフォーマンスのためにはパーティションを積極的に使っていく必要あり ファイルフォーマットの作成 CREATE FILE FORMAT csv_format TYPE = 'CSV' COMPRESSION = 'AUTO' FIELD_DELIMITER = ',' RECORD_DELIMITER = '\n' SKIP_HEADER = 0 FIELD_OPTIONALLY_ENCLOSED_BY = NONE DATE_FORMAT = 'AUTO' TIMESTAMP_FORMAT = 'AUTO' NULL_IF = (''); 外部ステージの作成 下記で作成した外部ステージを使用。IAMの設定などもこちらを参照。 S3(外部ステージ)からSnowflakeにデータロードする | my opinion is my own zatoima#COMPUTE_WH@TESTDB.PUBLIC>show stages; +-------------------------------+--------------+---------------+-------------+-----------------------------+-----------------+--------------------+--------------+---------+----------------+----------+-------+----------------------+------------------------------+ | created_on | name | database_name | schema_name | url | has_credentials | has_encryption_key | owner | comment | region | type | cloud | notification_channel | storage_integration | |-------------------------------+--------------+---------------+-------------+-----------------------------+-----------------+--------------------+--------------+---------+----------------+----------+-------+----------------------+------------------------------| | 2022-08-23 22:45:45.523 -0700 | S3_EXT_STAGE | TESTDB | PUBLIC | s3://snowflake-bucket-work/ | N | N | ACCOUNTADMIN | | ap-northeast-1 | EXTERNAL | AWS | NULL | SNOWFLAKE_AND_S3_INTEGRATION | +-------------------------------+--------------+---------------+-------------+-----------------------------+-----------------+--------------------+--------------+---------+----------------+----------+-------+----------------------+------------------------------+ 1 Row(s) produced. Time Elapsed: 0.077s 外部テーブルの構築 CREATE EXTERNAL TABLE t1 WITH location = @S3_EXT_STAGE auto_refresh = true file_format = csv_format; auto_refreshをTRUEにした場合においてもS3側のファイルに変更があった場合は更新を行う必要がある。AWSのS3の場合は次の設定を事前に行う必要がある。 Amazon S3に対する外部テーブルの自動更新 — Snowflake Documentation zatoima#COMPUTE_WH@TESTDB.PUBLIC>ALTER EXTERNAL TABLE t1 refresh; +--------+-------------------+-----------------------------------------+ | file | status | description | |--------+-------------------+-----------------------------------------| | t1.csv | REGISTERED_UPDATE | File registered (updated) successfully. | +--------+-------------------+-----------------------------------------+ 1 Row(s) produced. Time Elapsed: 0.480s zatoima#COMPUTE_WH@TESTDB.PUBLIC> zatoima#COMPUTE_WH@TESTDB.PUBLIC>select * from t1; +-----------------------------------------+ | VALUE | |-----------------------------------------| | { | | "c1": "0", | | "c2": "111111", | | "c3": "222222", | | "c4": " 1", | | "c5": "2022-08-23 22:47:44.214 -0700" | | } | | { | | "c1": "1", | | "c2": "111111", | | "c3": "222222", | | "c4": " 2", | | "c5": "2022-08-23 22:47:44.214 -0700" | | } | +-----------------------------------------+ 2 Row(s) produced. Time Elapsed: 1.077s zatoima#COMPUTE_WH@TESTDB.PUBLIC> 更新の状況はSYSTEM$EXTERNAL_TABLE_PIPE_STATUS('テーブル名');で確認ができる。 zatoima#COMPUTE_WH@TESTDB.PUBLIC>select SYSTEM$EXTERNAL_TABLE_PIPE_STATUS('T1'); +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | SYSTEM$EXTERNAL_TABLE_PIPE_STATUS('T1') | |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | {"executionState":"RUNNING","pendingFileCount":0,"notificationChannelName":"arn:aws:sqs:ap-northeast-1:xxxxx:sf-snowpipe-xxxx-88QZUsuy_HLwocQAHjHNUA","numOutstandingMessagesOnChannel":0,"lastPulledFromChannelTimestamp":"2022-08-25T07:24:54.217Z"} | +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ SYSTEM$EXTERNAL_TABLE_PIPE_STATUS( 実行ログ zatoima#COMPUTE_WH@TESTDB.PUBLIC>CREATE EXTERNAL TABLE t1 WITH location = @S3_EXT_STAGE auto_refresh = true file_format = csv_format; +--------------------------------+ | status | |--------------------------------| | Table T1 successfully created. | +--------------------------------+ 1 Row(s) produced. Time Elapsed: 4.079s zatoima#COMPUTE_WH@TESTDB.PUBLIC> zatoima#COMPUTE_WH@TESTDB.PUBLIC>show tables; +-------------------------------+----------+---------------+-------------+-------+---------+------------+------+-------+--------------+----------------+----------------------+-----------------+-------------+ | created_on | name | database_name | schema_name | kind | comment | cluster_by | rows | bytes | owner | retention_time | automatic_clustering | change_tracking | is_external | |-------------------------------+----------+---------------+-------------+-------+---------+------------+------+-------+--------------+----------------+----------------------+-----------------+-------------| | 2022-08-14 05:17:22.196 -0700 | LINEITEM | TESTDB | PUBLIC | TABLE | | | 0 | 0 | ACCOUNTADMIN | 1 | OFF | OFF | N | | 2022-08-25 00:05:01.262 -0700 | T1 | TESTDB | PUBLIC | TABLE | | | NULL | 0 | ACCOUNTADMIN | 1 | OFF | OFF | Y | +-------------------------------+----------+---------------+-------------+-------+---------+------------+------+-------+--------------+----------------+----------------------+-----------------+-------------+ 2 Row(s) produced. Time Elapsed: 0.146s zatoima#COMPUTE_WH@TESTDB.PUBLIC> zatoima#COMPUTE_WH@TESTDB.PUBLIC> zatoima#COMPUTE_WH@TESTDB.PUBLIC>select * from t1; +-----------------------------------------+ | VALUE | |-----------------------------------------| | { | | "c1": "0", | | "c2": "111111", | | "c3": "222222", | | "c4": "1", | | "c5": "2022-08-23 22:47:44.214 -0700" | | } | | { | | "c1": "1", | | "c2": "111111", | | "c3": "222222", | | "c4": "2", | | "c5": "2022-08-23 22:47:44.214 -0700" | | } | ~~省略~~ zatoima#COMPUTE_WH@TESTDB.PUBLIC>SELECT value :c1, value :c2, value :c3, value :c4, value :c5 FROM t1 LIMIT 10 ; +-----------+-----------+-----------+-----------+---------------------------------+ | VALUE :C1 | VALUE :C2 | VALUE :C3 | VALUE :C4 | VALUE :C5 | |-----------+-----------+-----------+-----------+---------------------------------| | "0" | "111111" | "222222" | "1" | "2022-08-23 22:47:44.214 -0700" | | "1" | "111111" | "222222" | "2" | "2022-08-23 22:47:44.214 -0700" | | "2" | "111111" | "222222" | "3" | "2022-08-23 22:47:44.214 -0700" | | "3" | "111111" | "222222" | "4" | "2022-08-23 22:47:44.214 -0700" | | "4" | "111111" | "222222" | "5" | "2022-08-23 22:47:44.214 -0700" | | "5" | "111111" | "222222" | "6" | "2022-08-23 22:47:44.214 -0700" | | "6" | "111111" | "222222" | "7" | "2022-08-23 22:47:44.214 -0700" | | "7" | "111111" | "222222" | "8" | "2022-08-23 22:47:44.214 -0700" | | "8" | "111111" | "222222" | "9" | "2022-08-23 22:47:44.214 -0700" | | "9" | "111111" | "222222" | "10" | "2022-08-23 22:47:44.214 -0700" | +-----------+-----------+-----------+-----------+---------------------------------+ 10 Row(s) produced. Time Elapsed: 0.653s 参照 外部テーブルの概要 — Snowflake Documentation --- ### SQLで重複抽出 date: 2022-10-11 url: https://zatoima.github.io/sql-leetcode-182-duplicate-search/ tags: SQL 色々方法があるんだな、というLeetcodeのメモです。 Duplicate Emails テーブル mysql> select * from Person; +------+---------+ | id | email | +------+---------+ | 1 | a@b.com | | 2 | c@d.com | | 3 | a@b.com | +------+---------+ HAVING句を使う select Email from Person group by Email having count(Email) > 1; サブクエリ select Email from ( select Email, count(Email) as num from Person group by Email ) as statistic where num > 1 ; 自己結合 select distinct a.email from Person as a join Person as b on a.email = b.email where a.Id <> b.Id --- ### MacでiCloud Driveへのディレクトリ移動をしやすくする date: 2022-10-10 url: https://zatoima.github.io/Mac-icloud-drive-ln-create/ tags: Mac iCloudの場所がややこしくて一発で移動しにくいのでシンボリックリンクを作成。 ln -s $HOME/Library/Mobile\ Documents/com~apple~CloudDocs/ $HOME/iCloud $HOME配下に設定。これで移動しやすくなったはず。 (base) zatoima@M1MBA ~ % ls -l $HOME/iCloud lrwxr-xr-x 1 zatoima staff 60 10 10 10:59 /Users/zatoima/iCloud -> /Users/zatoima/Library/Mobile Docu --- ### Docker上のPostgreSQLへCopyする際のコマンド date: 2022-10-02 url: https://zatoima.github.io/docker-postgresql-copy-host-to-docker/ tags: Docker, PostgreSQL 前準備 対象ファイルの生成。MoneyForwardの家計簿詳細データをPostgreSQLへ突っ込んでいます。文字コードとか不要な行などを消しています。 cat 収入・支出詳細_*.csv > import.csv nkf -w --overwrite import.csv sed -i '/計算対象/d' import.csv sed -i -e "s/\"-/\"/g" import.csv Docker側のホストへファイルをコピーをした上で実行する想定 docker cp import.csv docker_postgres_1:/tmp/import.csv docker exec docker_postgres_1 cat /tmp/import.csv docker exec -it docker_postgres_1 psql -U postgres metabase -c "truncate table kakeibo" docker exec -it docker_postgres_1 psql -U postgres metabase -c "COPY kakeibo FROM '/tmp/import.csv' with csv header encoding 'UTF8'" 補足 DDLメモ docker exec -it docker_postgres_1 psql -U postgres metabase drop table kakeibo; CREATE TABLE public.kakeibo ( target_flg numeric, target_date date, item_detail text, ammount numeric, bank text, primary_item character varying(30), secondary_item character varying(30), item_memo text, transfer_flg numeric, item_id character varying(30) ); --- ### Google Spreadsheetで特定時点の為替や株価を取得 date: 2022-09-30 url: https://zatoima.github.io/google-spreadsheet-googlefinance-currency/ tags: その他 GOOGLEFINANCE関数だけを使用するとDateとClose時点のPriceを指定してしまう。 =GOOGLEFINANCE("CURRENCY:USDJPY", "price", "2019/8/1") 関数をindex(..., 2, 2)でラップして、2行目の2番目のセルだけを取得 =index(GOOGLEFINANCE("CURRENCY:USDJPY", "price", "2019/8/1"), 2, 2) 特定企業の株価を取得。こちらもIndex関数を使用してほしい情報のみを取得 =index(GOOGLEFINANCE("NASDAQ:AMZN", "price", "2019/8/1"), 2, 2) --- ### Snowflakeのキャッシュ date: 2022-09-30 url: https://zatoima.github.io/snowflake-cached-memo/ tags: snowflake # キャッシュ名 キャッシュ対象 使用可能なユーザー 保存レイヤー 有効期間 1 結果キャッシュ クエリの結果 クエリが実行された同じロールのすべてのユーザー Snowflake 24時間 2 メタデータキャッシュ テーブルに関する情報 すべてのユーザー Snowflake 常に 3 データキャッシュ クエリ結果のファイルヘッダとカラムデータ 同じ仮想ウェアハウスを実行したユーザー ウェアハウス(SSD) ウェアハウスの稼働中 コンパイルキャッシュは存在せず常にコンパイルが必要 キャッシュを使用しないようにするためには?? 結果キャッシュ USE_CACHED_RESULTをFALSEに メタデータキャッシュ 方法無し データキャッシュ ウェアハウスのSUSPENDなど Snowflakeのデータキャッシュの無効化 | my opinion is my own 注意事項 結果キャッシュ https://docs.snowflake.com/ja/user-guide/querying-persisted-results.html#retrieval-optimization 通常、次の条件の すべて が満たされる場合、クエリ結果が再利用されます。 新しいクエリは、以前に実行したクエリと構文的に一致する。 クエリには、実行時に評価する必要のある関数が含まれていない(例: CURRENT_TIMESTAMP() および UUID_STRING())。 CURRENT_DATE() 関数はこのルールの例外です。CURRENT_DATE() は実行時に評価されますが、 CURRENT_DATE() を使用するクエリは、クエリ再利用機能を引き続き使用できます。 クエリには、 ユーザー定義関数(UDFs) または 外部関数 が含まれていない。 クエリ結果に寄与するテーブルデータが変更されていない。 以前のクエリの永続化された結果が引き続き利用可能である。 キャッシュされた結果にアクセスするロールには、必要な権限がある。 クエリが SELECT クエリの場合、クエリを実行するロールには、キャッシュされたクエリで使用されるすべてのテーブルに必要なアクセス権限が必要です。 クエリが SHOW クエリの場合、クエリを実行するロールは、キャッシュされた結果を生成したロールと一致する必要があります。 結果の生成方法に影響する構成オプションが変更されていない。 テーブル内にある他のデータ変更によって、テーブルのマイクロパーティションが変更されていない(例: 再クラスタ化または統合化)。 これらの条件をすべて満たしても、Snowflakeがクエリ結果を再利用することは 保証されません。 参照 Snowflakeの3つのキャッシュ 保存済みのクエリ結果の使用 — Snowflake Documentation --- ### Snowflakeで名字と名前を抽出する(POSITION関数) date: 2022-09-29 url: https://zatoima.github.io/snowflake-extract-name-position-function/ tags: Snowflake, SQL 名前の名字と名前を抽出する(スペース区切りの場合) 対象データ imazaj#XSMALL@SQLDB.PUBLIC>select name from CUSTOMERS limit 5; +-------------+ | NAME | |-------------| | 石塚 拓 | | 長坂 賢介 | | 野中 裕之 | | 髙松 龍 | | 小倉 慎太郎 | +-------------+ Position関数を使う。PostgreSQLの場合のSTRPOS、Oracleの場合のINSTR。 POSITION — Snowflake Documentation POSITION( <expr1>, <expr2> [ , <start_pos> ] ) POSITION( <expr1> IN <expr2> ) 引数 必須: expr1 検索する値を表す文字列またはバイナリ式。 expr2 検索する値を表す文字列またはバイナリ式。 オプション: start_pos 検索を開始する位置を示す番号です(1 は expr2 の開始を表します)。 デフォルト: 1 select name, SUBSTR(name, 1, POSITION(' ', name) -1) as lastname, SUBSTR(name, POSITION(' ', name)) as firstname from customers limit 5; imazaj#XSMALL@SQLDB.PUBLIC>select name, SUBSTR(name, 1, POSITION(' ', name) -1) as lastname, SUBSTR(name, POSITION(' ', name)) as firstname from customers limit 5; +-------------+----------+-----------+ | NAME | LASTNAME | FIRSTNAME | |-------------+----------+-----------| | 石塚 拓 | 石塚 | 拓 | | 長坂 賢介 | 長坂 | 賢介 | | 野中 裕之 | 野中 | 裕之 | | 髙松 龍 | 髙松 | 龍 | | 小倉 慎太郎 | 小倉 | 慎太郎 | +-------------+----------+-----------+ 5 Row(s) produced. Time Elapsed: 0.974s --- ### Snowflakeのデータキャッシュの無効化 date: 2022-09-28 url: https://zatoima.github.io/snowflake-data-cache-disabled/ tags: snowflake Snowflakeの結果キャッシュはパラメータを変更することで無効化することが出来るが、データキャッシュを無効化することは出来るのか?と思い確認してみた。 結論 ウェアハウスの一時停止、再開を行う。 ウェアハウスに関する考慮事項 — Snowflake Documentation ウェアハウスが一時停止されると、このキャッシュはドロップされるため、ウェアハウスの再開後、一部のクエリの初期パフォーマンスが低下する可能性があります。再開されたウェアハウスが実行され、より多くのクエリが処理されると、キャッシュが再構築され、キャッシュを利用できるクエリのパフォーマンスが向上します。 SHOW WAREHOUSES; ALTER WAREHOUSE IF EXISTS XSMALL SUSPEND; SHOW WAREHOUSES; ALTER WAREHOUSE XSMALL RESUME IF SUSPENDED; SHOW WAREHOUSES; SQL SELECT l_returnflag, l_linestatus, SUM(l_quantity) AS sum_qty, SUM(l_extendedprice) AS sum_base_price, SUM(l_extendedprice * (l_discount)) AS sum_disc_price, SUM(l_extendedprice * (l_discount) * (1+l_tax)) AS sum_charge, AVG(l_quantity) AS avg_qty, AVG(l_extendedprice) AS avg_price, AVG(l_discount) AS avg_disc, COUNT(*) AS count_order FROM lineitem WHERE l_shipdate <= dateadd(day, 90, to_date('1998-12-01')) GROUP BY l_returnflag, l_linestatus ORDER BY l_returnflag, l_linestatus; 初回実行 リモートディスク(S3)からの読み取りが発生する。キャッシュからスキャンされた割合も当然0%となる。 何もしない状態で2回実行した際のクエリプロファイル 結果キャッシュを使用することで高速に完了する クエリ結果キャッシュの無効化 SHOW PARAMETERS LIKE '%USE_CACHED_RESULT%'; ALTER SESSION SET USE_CACHED_RESULT = FALSE; 結果キャッシュは使用されずともデータキャッシュから読み取られている。(ウェアハウスのサイズが小さいのですべてがキャッシュに乗り切れていないのかもしれない。) データキャッシュを無効化する方法について Is it possible to clear the cache? https://community.snowflake.com/s/question/0D50Z00008SNECoSAP/is-it-possible-to-clear-the-cache Aside from the USE_CACHED_RESULT session parameter, is there any way to force the warehouse cache to disable? https://community.snowflake.com/s/question/0D70Z000001l2ovSAA/detail 上記に記載の通り、コマンドとしては用意されていないようなので、ウェアハウスの停止、起動を行うことでデータキャッシュを使用されないようにする。 ウェアハウスに関する考慮事項 — Snowflake Documentation ウェアハウスが一時停止されると、このキャッシュはドロップされるため、ウェアハウスの再開後、一部のクエリの初期パフォーマンスが低下する可能性があります。再開されたウェアハウスが実行され、より多くのクエリが処理されると、キャッシュが再構築され、キャッシュを利用できるクエリのパフォーマンスが向上します。 SHOW WAREHOUSES; ALTER WAREHOUSE IF EXISTS XSMALL SUSPEND; SHOW WAREHOUSES; ALTER WAREHOUSE XSMALL RESUME IF SUSPENDED; SHOW WAREHOUSES; キャッシュからスキャンされた割合が0%に。 参考 Snowflakeの3種類のキャッシュについてお勉強してみた #SnowflakeDB | DevelopersIO --- ### Hugo wowchemyのシンタックスハイライト変更 date: 2022-09-26 url: https://zatoima.github.io/hugo-wowchemy-syntax-highlight-setting/ tags: Hugo 端末移行に伴いHugo(本ブログの実行環境)を移行中。シンタックスハイライトの変更方法がわからなくなってしまって調べたのでメモ。 zatoima@M1MBA zatoima.github.io % pwd /Users/zatoima/work/hugo/zatoima.github.io zatoima@M1MBA zatoima.github.io % zatoima@M1MBA zatoima.github.io % mkdir -p assets/css/libs/chroma/ zatoima@M1MBA zatoima.github.io % hugo gen chromastyles --style=monokai > assets/css/libs/chroma/monokai.css zatoima@M1MBA zatoima.github.io % ls -l assets/css/libs/chroma/monokai.css -rw-r--r-- 1 zatoima staff 4394 9 26 17:15 assets/css/libs/chroma/monokai.css syntax_highlighter部分を変更する zatoima@M1MBA zatoima.github.io % cat config/_default/params.yaml # SITE SETUP # Guide: https://wowchemy.com/docs/getting-started/ # Documentation: https://wowchemy.com/docs/ # This file is formatted using YAML syntax - learn more at https://learnxinyminutes.com/docs/yaml/ features: syntax_highlighter: theme_light: monokai theme_dark: monokai math: enable: false 〜省略〜 https://wowchemy.com/docs/getting-started/customization/#code-syntax-highlighting Code syntax highlighting Hugo’s code syntax highlighter is named Chroma. How can we customize Chroma’s light and dark styles? Check out the languages and styles which Hugo supports at the Chroma Playground Choose from one of the built-in styles including: github-light github-dark dracula or import a Hugo Chroma style to your assets/css/libs/chroma/ folder (creating the folders as needed). For example, to import the xcode style as xcode-light and xcode-dark as xcode-dark: mkdir -p assets/css/libs/chroma/ hugo gen chromastyles --style=xcode > assets/css/libs/chroma/xcode-light.css hugo gen chromastyles --style=xcode-dark > assets/css/libs/chroma/xcode-dark.css Once you have chosen your styles, reference them in params.yaml: features: syntax_highlighter: theme_light: xcode-light theme_dark: xcode-dark こんな感じのシンタックスハイライトに。 --- ### metabase起動時のInitialization FAILEDエラー対応 date: 2022-09-19 url: https://zatoima.github.io/docker-metabase-initialization-failed-error/ tags: metabase エラーメッセージ 2022-09-17 15:51:59,306 INFO driver.impl :: Registered driver :presto-jdbc (parents: [:presto-common]) 🚚 2022-09-17 15:51:59,309 DEBUG plugins.lazy-loaded-driver :: Registering lazy loading driver :presto... 2022-09-17 15:51:59,317 INFO driver.impl :: Registered driver :presto (parents: [:presto-common]) 🚚 2022-09-17 15:51:59,320 INFO metabase.core :: Setting up and migrating Metabase DB. Please sit tight, this may take a minute... 2022-09-17 15:51:59,323 INFO db.setup :: Verifying h2 Database Connection ... 2022-09-17 15:51:59,891 INFO db.setup :: Successfully verified H2 1.4.197 (2018-03-18) application database connection. ✅ 2022-09-17 15:51:59,893 INFO db.setup :: Running Database Migrations... 2022-09-17 15:51:59,894 INFO db.setup :: Setting up Liquibase... 2022-09-17 15:52:00,474 ERROR metabase.core :: Metabase Initialization FAILED org.h2.jdbc.JdbcBatchUpdateException: The database is read only; SQL statement: UPDATE DATABASECHANGELOG SET FILENAME = ? [90097-197] at org.h2.jdbc.JdbcPreparedStatement.executeBatch(JdbcPreparedStatement.java:1295) at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:2544) H2データベースではなく、ローカルに構築しているPostgreSQLを使用するように環境変数を設定する。 Migrating to a production application database export MB_DB_TYPE=postgres export MB_DB_CONNECTION_URI="jdbc:postgresql://localhost:5432/metabase?user=postgres&password=postgres" java -jar metabase.jar 正常に起動した。 2022-09-17 15:54:30,330 INFO metabase.core :: Metabase Initialization COMPLETE https://discourse.metabase.com/t/error-the-database-is-read-only-unable-to-connect-me-12780/10651/3 https://www.metabase.com/docs/latest/installation-and-operation/migrating-from-h2 --- ### ArmのDocker環境でMetabase構築 date: 2022-09-17 url: https://zatoima.github.io/docker-metabase-arm-postgresql-env/ tags: Docker 以前、MetabaseをEC2のt2.microで構築したのだが、メモリ系が辛いので移行を検討。そして、metabaseとpostgresをサクサクと動かしたかったので、Oracle Cloudのalways free環境(4OCPU、24GB、Arm)を使ってみる。 シェイプの構成 シェイプ: VM.Standard.A1.Flex OCPU数: 4 ネットワーク帯域幅(Gbps): 4 メモリー(GB): 24 ローカル・ディスク: ブロック・ストレージのみ [opc@oci-arm metabase]$ cat /etc/os-release NAME="Oracle Linux Server" VERSION="7.9" ID="ol" ID_LIKE="fedora" VARIANT="Server" VARIANT_ID="server" VERSION_ID="7.9" PRETTY_NAME="Oracle Linux Server 7.9" ANSI_COLOR="0;31" CPE_NAME="cpe:/o:oracle:linux:7:9:server" HOME_URL="https://linux.oracle.com/" BUG_REPORT_URL="https://bugzilla.oracle.com/" ORACLE_BUGZILLA_PRODUCT="Oracle Linux 7" ORACLE_BUGZILLA_PRODUCT_VERSION=7.9 ORACLE_SUPPORT_PRODUCT="Oracle Linux" ORACLE_SUPPORT_PRODUCT_VERSION=7.9 Docker [opc@oci-arm metabase]$ docker-compose -v docker-compose version 1.29.2, build unknown [opc@oci-arm metabase]$ docker -v Docker version 19.03.11-ol, build 9bb540d [opc@oci-arm metabase]$ ディレクトリ構造 [opc@oci-arm docker]$ tree . ├── docker-compose.yaml ├── metabase │ ├── data │ └── Dockerfile └── postgres ├── data └── init └── create_db.sql docker-compose.yaml version: '3' services: metabase: build: ./metabase container_name: metabase ports: - 3000:3000 volumes: - ./metabase/data:/metabase-data environment: - MB_DB_FILE=/metabase-data/metabase.db postgres: image: arm32v7/postgres:latest ports: - 5432:5432 volumes: - ./postgres/data:/var/lib/postgresql/data - ./postgres/init:/docker-entrypoint-initdb.d environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres metabaseのDockerfile Armなのですんなりとはいかなかった。下記のgithubの記載を参考に。リンク先のDockerfileではubuntuのバージョンが古く、apt-getが動作しなかったので、バージョンを最新にした。 https://github.com/metabase/metabase/issues/13119#issuecomment-1000350647 FROM ubuntu:latest ENV FC_LANG en-US LC_CTYPE en_US.UTF-8 # dependencies RUN apt-get update -yq && apt-get install -yq bash fonts-dejavu-core fonts-dejavu-extra fontconfig curl openjdk-11-jre-headless && \ apt-get clean && \ rm -rf /var/lib/{apt,dpkg,cache,log}/ && \ mkdir -p /app/certs && \ curl https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem -o /app/certs/rds-combined-ca-bundle.pem && \ keytool -noprompt -import -trustcacerts -alias aws-rds -file /app/certs/rds-combined-ca-bundle.pem -keystore /etc/ssl/certs/java/cacerts -keypass changeit -storepass changeit && \ curl https://cacerts.digicert.com/DigiCertGlobalRootG2.crt.pem -o /app/certs/DigiCertGlobalRootG2.crt.pem && \ keytool -noprompt -import -trustcacerts -alias azure-cert -file /app/certs/DigiCertGlobalRootG2.crt.pem -keystore /etc/ssl/certs/java/cacerts -keypass changeit -storepass changeit && \ mkdir -p /plugins && chmod a+rwx /plugins && \ useradd --shell /bin/bash metabase WORKDIR /app # copy app from the offical image COPY --from=metabase/metabase:latest /app /app RUN chown -R metabase /app USER metabase # expose our default runtime port EXPOSE 3000 # run it ENTRYPOINT ["/app/run_metabase.sh"] docker-compose [opc@oci-arm metabase]$ docker-compose up -d Creating network "docker_default" with the default driver Creating docker_postgres_1 ... done Creating metabase ... done [opc@oci-arm metabase]$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c74acd420716 arm32v7/postgres:latest "docker-entrypoint.s…" 5 seconds ago Up 4 seconds 0.0.0.0:5432->5432/tcp docker_postgres_1 d15ea2032f2d docker_metabase "/app/run_metabase.sh" 5 seconds ago Up 4 seconds 0.0.0.0:3000->3000/tcp metabase 接続確認 http://“Public IP”:3000/auth/login PostgreSQLの設定変更 postgresql.confでパラメータ変更 [root@oci-arm data]# grep "share" postgresql.conf shared_buffers = 2048MB # min 128kB metabase=# show shared_buffers; shared_buffers ---------------- 2GB (1 row) --- ### AWSのエンコードされたエラーメッセージを見る方法 date: 2022-09-15 url: https://zatoima.github.io/aws-encode-error-message-how-to-confirm/ tags: AWS aws sts decode-authorization-messageを使う [ec2-user@bastin ~]$ aws sts decode-authorization-message --encoded-message CVOAvQdSoEIR4<省略> { "DecodedMessage": "{\"allowed\":false,\"explicitDeny\":false,\"matchedStatements\":{\"items\":[]},\"failures\":{\"items\":[]},\"context\":{\"principal\":{\"id\":\"AROAR23YLZYEOUMEHOE2O:AWSBackup-AWSBackupROLEEC2\",\"arn\":\"arn:aws:sts::xxxxxx:assumed-role/AWSBackupROLEEC2/AWSBackup-AWSBackupROLEEC2\"},\"action\":\"iam:PassRole\",\"resource\":\"arn:aws:iam::xxxxxx:role/IAM_ROLE_EC2_Access\",\"conditions\":{\"items\":[{\"key\":\"aws:Region\",\"values\":{\"items\":[{\"value\":\"ap-northeast-1\"}]}},{\"key\":\"aws:Service\",\"values\":{\"items\":[{\"value\":\"ec2\"}]}},{\"key\":\"aws:Resource\",\"values\":{\"items\":[{\"value\":\"role/IAM_ROLE_EC2_Access\"}]}},{\"key\":\"iam:RoleName\",\"values\":{\"items\":[{\"value\":\"IAM_ROLE_EC2_Access\"}]}},{\"key\":\"aws:Type\",\"values\":{\"items\":[{\"value\":\"role\"}]}},{\"key\":\"aws:Account\",\"values\":{\"items\":[{\"value\":\"xxxxxx\"}]}},{\"key\":\"aws:ARN\",\"values\":{\"items\":[{\"value\":\"arn:aws:iam::xxxxxx:role/IAM_ROLE_EC2_Access\"}]}}]}}}" --- ### SnowPro Advanced Architect対策メモ date: 2022-09-10 url: https://zatoima.github.io/snowflake-certificate-snowpro-advanced-memo/ tags: snowflake SNOWPRO ADVANCED: ARCHITECT EXAM STUDY GUIDE(2022/9/7版)に記載のある内容を参考にしつつ、参考Docを試験ガイドの項目にマッピングしたもの。SNOWPRO ADVANCED: ARCHITECT EXAM STUDY GUIDEが頻繁にアップデートされていることとリンク切れをたまに起こしているところは注意する必要があるかも。また試験の使用言語が英語しかないので、単語に慣れる意味でも英語版のマニュアルや資料を読もうと思う。 公式ガイド https://www.snowflake.com/certifications/?lang=ja 試験ガイド 1.0 Domain: Account and Security 1.1 Design a Snowflake account and database strategy, based on business requirements. Create and configure Snowflake parameters based on a central account and any additional accounts. Account Usage — Snowflake Documentation List the benefits and limitations of one Snowflake account as compared to multiple Snowflake accounts. 1.2 Design an architecture that meets data security, privacy, compliance, and governance requirements. Configure Role Based Access Control (RBAC) hierarchy Overview of Access Control — Snowflake Documentation System roles and associated best practices Data Access Understanding Column-level Security — Snowflake Documentation CREATE STORAGE INTEGRATION — Snowflake Documentation Working with Secure Views — Snowflake Documentation Data Consumers — Snowflake Documentation General Limitations for Shared Databases Data Security Compliance 1.3 Outline Snowflake security principles and identify use cases where they should be applied. Managing Security in Snowflake — Snowflake Documentation Encryption ENCRYPT — Snowflake Documentation Network security Azure Private Link & Snowflake — Snowflake Documentation SYSTEM$WHITELIST_PRIVATELINK — Snowflake Documentation User, Role, Grants provisioning Overview of Access Control — Snowflake Documentation Authentication Multi-Factor Authentication (MFA) — Snowflake Documentation Managing/Using Federated Authentication — Snowflake Documentation STUDY GUIDEには参考資料として掲載されているが、上記の1.1~1.3のどこに紐づくかわからないもの ALTER ACCOUNT — Snowflake Documentation Parameters — Snowflake Documentation WhitePaper/Read Assets Cloud Data Platform Security: How Snowflake Sets the Standard https://resources.snowflake.com/white-paper/cloud-data-platform-security-how-snowflake-sets-the-standard#main-content Lab Guides Snowflake Pattern - Security - Access to Sensitive Objects https://resources.snowflake.com/architecture-patterns/snowflake-pattern-security-access-to-sensitive-objects Snowflake Pattern - Security - Authentication https://resources.snowflake.com/architecture-patterns/snowflake-pattern-security-authentication Snowflake Pattern - Security - Network Architecture https://resources.snowflake.com/architecture-patterns/snowflake-pattern-security-network-architecture 2.0 Domain:Snowflake Architecture 2.1 Outline the benefits and limitations of various data models in a Snowflake environment. Data models 2.2 Design data sharing solutions, based on different use cases. Use Cases Sharing within the same organization/same Snowflake account Sharing within a cloud region Sharing across cloud regions Sharing between different Snowflake accounts Introduction to Database Replication Across Multiple Accounts — Snowflake Documentation Sharing to a non-Snowflake customer Sharing Across platforms Data Exchange Data Providers — Snowflake Documentation Data Sharing Methods Data Providers — Snowflake Documentation Sharing Data Securely in Snowflake — Snowflake Documentation 2.3 Create architecture solutions that support Development Lifecycles as well as workload requirements. Data Lake and Environments Working with External Tables — Snowflake Documentation Introduction to External Tables — Snowflake Documentation Integrating Apache Hive Metastores with Snowflake — Snowflake Documentation Workloads Development lifecycle support 2.4 Given a scenario, outline how objects exist within the Snowflake Object hierarchy and how the hierarchy impacts an architecture. Roles CREATE USER — Snowflake Documentation Overview of Access Control — Snowflake Documentation Warehouses Object hierarchy Database 2.5 Determine the appropriate data recovery solution in Snowflake and how data can be restored. Backup/Recovery Cloning Considerations — Snowflake Documentation Understanding & Using Time Travel — Snowflake Documentation Disaster Recovery Database Replication and Failover/Failback — Snowflake Documentation Introduction to Database Replication Across Multiple Accounts — Snowflake Documentation Lab Guides Building an application on Snowflake with data from Snowflake Data Marketplace Getting Started with Time Travel Data Modeling | Snowflake WhitePaper/Read Assets SNO-eBook-7-Reference-Architectures-for-Application-Builders-AppHealth-SecurityAna.pdf Support Multiple Data Modeling Approaches with Snowflake Data Modeling in the Age of JSON and Schema-on-Read - Snowflake Blog Different Types of Objects in Snowflake 3.0 Domain: Data Engineering 3.1 Determine the appropriate data loading or data unloading solution to meet business needs. Data sources Ingestion of the data Architecture Changes Data unloading 3.2 Outline key tools in Snowflake’s ecosystem and how they interact with Snowflake. Connectors Connectors & Drivers — Snowflake Documentation Kafka Spark Python Using the Python Connector — Snowflake Documentation Drivers JDBC OBDC API endpoints SnowSQL 3.3 Determine the appropriate data transformation solution to meet business needs. Materialized Views, Views and Secure Views Staging layers and tables Loading Data into Snowflake — Snowflake Documentation Unloading Data from Snowflake — Snowflake Documentation Querying semi-structured data Semi-structured Data — Snowflake Documentation Semi-structured Data Types — Snowflake Documentation Querying Semi-structured Data — Snowflake Documentation Data processing Continuous Data Pipelines — Snowflake Documentation Introduction to Snowpipe — Snowflake Documentation Stored Procedures Understanding Caller’s Rights and Owner’s Rights Stored Procedures — Snowflake Documentation Stored Procedures — Snowflake Documentation Streams and Tasks CREATE STREAM — Snowflake Documentation Functions WhitePaper/Read Assets Snowflake For Data Engineering - Easily Ingest, Transform, And Deliver Data For Up-To-The-Moment Ins Using Streams and Tasks in Snowflake Masking Semi-Structured Data with Snowflake - Snowflake Blog Easy Continuous Data Pipelines with GA of Streams and Tasks - Snowflake Blog Lab Guides Building a Real-Time Data Vault in Snowflake Enrich Salesforce data with Snowflake to deliver your Customer 360 Auto-Ingest Twitter Data into Snowflake Build a Recommendation Engine with AWS SageMaker Getting Started with Snowpipe Accelerating Data Teams with dbt Cloud & Snowflake Getting Started With User-Defined SQL Functions Getting Started with Python Getting Started with SnowSQL 4.0 Domain: Performance Optimization 4.1 Outline performance tools, best practices, and appropriate scenarios where they should be applied. Query profiling Virtual Warehouse configuration Virtual Warehouses — Snowflake Documentation Micro-partitions & Data Clustering — Snowflake Documentation Clustering Clustering Keys & Clustered Tables — Snowflake Documentation Search Optimization Using the Search Optimization Service — Snowflake Documentation Using Persisted Query Results — Snowflake Documentation Caching Query rewrite 4.2 Troubleshoot performance issues with existing architectures. JOIN explosions MERGE — Snowflake Documentation Warehouse selection (scaling up as compared to scaling out) Best practices and optimization techniques Working with Materialized Views — Snowflake Documentation Duplication of data WhitePaper/Read Assets https://developers.snowflake.com/wp-content/uploads/2020/09/SNO-eBook-7-Reference-Architectures-for-Application-Builders-Customer360-2.pdf Lab Guides Resource Optimization: Performance Resource Optimization: Billing Metrics Resource Optimization: Setup & Configuration Resource Optimization: Usage Monitoring Automating Data Pipelines to Drive Marketing Analytics with Snowflake & Fivetran Building a Data Application DevOps: Database Change Management with schemachange and GitHub --- ### AWS BackupでEC2を復元しようとしたときの権限不足エラー date: 2022-09-08 url: https://zatoima.github.io/aws-backup-ec2-restore-error/ tags: AWS エラーメッセージ You are not authorized to perform this operation. Please consult the permissions associated with your AWS Backup role(s), and refer to the AWS Backup documentation for more details. Encoded authorization failure message: <省略> aws sts decode-authorization-message --encoded-message <エラーメッセージ>でデコードする。 Decodeメッセージ { "DecodedMessage": "{\"allowed\":false,\"explicitDeny\":false,\"matchedStatements\":{\"items\":[]},\"failures\":{\"items\":[]},\"context\":{\"principal\":{\"id\":\"AROAR23YLZYEOUMEHOE2O:AWSBackup-AWSBackupROLEEC2\",\"arn\":\"arn:aws:sts::xxxxxxxxxxxxx:assumed-role/AWSBackupROLEEC2/AWSBackup-AWSBackupROLEEC2\"},\"action\":\"iam:PassRole\",\"resource\":\"arn:aws:iam::xxxxxxxxxxxxx:role/IAM_ROLE_EC2_Access\",\"conditions\":{\"items\":[{\"key\":\"aws:Region\",\"values\":{\"items\":[{\"value\":\"ap-northeast-1\"}]}},{\"key\":\"aws:Service\",\"values\":{\"items\":[{\"value\":\"ec2\"}]}},{\"key\":\"aws:Resource\",\"values\":{\"items\":[{\"value\":\"role/IAM_ROLE_EC2_Access\"}]}},{\"key\":\"iam:RoleName\",\"values\":{\"items\":[{\"value\":\"IAM_ROLE_EC2_Access\"}]}},{\"key\":\"aws:Type\",\"values\":{\"items\":[{\"value\":\"role\"}]}},{\"key\":\"aws:Account\",\"values\":{\"items\":[{\"value\":\"xxxxxxxxxxxxx\"}]}},{\"key\":\"aws:ARN\",\"values\":{\"items\":[{\"value\":\"arn:aws:iam::xxxxxxxxxxxxx:role/IAM_ROLE_EC2_Access\"}]}}]}}}" } iam:PassRole系でエラーが起きているようだ。 下記記事の通り、追加のポリシーをアタッチする必要がある。 AWS Backup を使用して Amazon EC2 インスタンスを復元するときに表示されるエンコードされた認可エラーメッセージのトラブルシューティング EC2 の AMI からは復元できるが、AWS Backup から復元しようとするとエラーになった際の対処方法 | DevelopersIO 対象の EC2 を確認すると、IAM ロールがアタッチされていました。 この場合には復元する際に、新たに IAM ロールをアタッチする必要があります。 そのため、AWS Backup から復元する場合には、「AWS Backup 用のロール」に以下のように「EC2 にアタッチするロールを PassRole できる」権限を追加する必要があります。 { "Version": "2012-10-17", "Statement": [ { "Action": "iam:PassRole", "Resource": "arn:aws:iam::111122223333:role/*", "Effect": "Allow" } ] } --- ### Azure Text to Speechで英語テキストをPythonでmp3化する date: 2022-09-05 url: https://zatoima.github.io/python-azure-english-text-to-speech/ tags: Python, Azure, 英語 英語勉強時に文章を読み上げてくれる機能が欲しくて調べてみた。英語に関してはAWS、Azure、GCPのText to Speechサービスの中では一番Azureが流暢に感じる。 Azure [テキスト読み上げ – リアルな AI 音声ジェネレーター | Microsoft Azure] AWS Amazon Polly(深層学習を使用したテキスト読み上げサービス)| AWS Google Cloud Text-to-Speech: 自然な音声合成 | Google Cloud 参考にした記事 PythonでAzure Text to Speechで合成音声の作成 - Qiita 上記からの変更点 日本リージョンからEast USリージョンに変更 日本語のText to Speechではなく、英語でのText to Speechに変更 実行時に読み込ませるテキスト文を指定する形に。 text = input('Enter English Text : ') subscription_key = 'xxxxxxxxxx' # APIキーをいれてください import requests import xml.etree.ElementTree as ElementTree import datetime dt = datetime.datetime.now() dt = dt.strftime('%Y%m%d%H%M%S') output="azure-text-to-speech_"+dt+".mp3" fetch_token_url = 'https://eastus.api.cognitive.microsoft.com/sts/v1.0/issuetoken' headers = { 'Ocp-Apim-Subscription-Key': subscription_key } response = requests.post(fetch_token_url, headers=headers) access_token = str(response.text) print(access_token) constructed_url = 'https://eastus.tts.speech.microsoft.com/cognitiveservices/v1' headers = { 'Authorization': 'Bearer ' + access_token, 'Content-Type': 'application/ssml+xml', 'X-Microsoft-OutputFormat': 'audio-16khz-128kbitrate-mono-mp3', } xml_body = ElementTree.Element('speak', version='1.0') xml_body.set('{http://www.w3.org/XML/1998/namespace}lang', 'en-US') voice = ElementTree.SubElement(xml_body, 'voice') voice.set('{http://www.w3.org/XML/1998/namespace}lang', 'en-US') voice.set('name', 'Microsoft Server Speech Text to Speech Voice (en-US, JennyNeural)') prosody = ElementTree.SubElement(voice, 'prosody') prosody.set('pitch','medium') # high prosody.set('rate','medium') # fast prosody.text = text body = ElementTree.tostring(xml_body) response = requests.post(constructed_url, headers=headers, data=body) if response.status_code == 200: with open(output, 'wb') as audio: audio.write(response.content) print("\nStatus code: " + str(response.status_code) + "\nYour TTS is ready for playback.\n") else: print("\nStatus code: " + str(response.status_code) + "\nSomething went wrong. Check your subscription key and headers.\n") --- ### AWS コスト管理のページで「このアクションを実行する権限がありません。」が表示される date: 2022-09-04 url: https://zatoima.github.io/aws-cost-management-action-error/ tags: AWS 画面 該当ページ IAMユーザにAdministratorAccess権限が付与されていてもコスト管理のページは見れない模様 アクセス許可の管理の概要 - AWS 請求 IAM アクセスをアクティベートするだけでは、これらの請求ンソールページに必要な許可は IAM ユーザーとロールに付与されません。IAM アクセスのアクティベートに加えて、必要な IAM ポリシーをこれらのユーザーまたはロールにアタッチする必要があります。詳細については、「AWS Billing でアイデンティティベースのポリシー (IAM ポリシー) を使用する」を参照してください。 [IAM アクセスをアクティベートする] 設定をアクティベートするには、ルートユーザーの認証情報を使用して AWS アカウントにログインしてから、マイアカウントページで設定を選択する必要があります。請求コンソールページへの IAM ユーザーおよびロールのアクセスを許可する各アカウントで、この設定をアクティベートします。AWS Organizations を使用する場合は、コンソールページへの IAM ユーザーとロールのアクセスを許可する各管理アカウントまたはメンバーアカウントでこの設定をアクティベートします。 手順 アクセス許可の管理の概要 - AWS 請求 請求情報とコスト管理コンソールへの IAM ユーザーおよびロールのアクセスをアクティベートするには ルートアカウント認証情報 (具体的には、AWS アカウントの作成に使用した E メールアドレスとパスワード) で AWS マネジメントコンソール にサインインします。 ナビゲーションバーでアカウント名を選択してから、[マイアカウント] を選択します。 [IAM User and Role Access to Billing Information] の横で、[Edit] を選択します。 [Activate IAM Access] (アクセスのアクティブ化) チェックボックスをオンにして、Billing and Cost Management ページへのアクセスをアクティブ化します。 [Update] (更新) を選択します。 正常にルートユーザ以外でもコスト管理の画面が見れるようになった --- ### Snowflakeでログイン履歴を確認する date: 2022-09-01 url: https://zatoima.github.io/snowflake-login-history/ tags: snowflake LOGIN_HISTORYビューを使用する 過去365日間(1年間)以内のSnowflakeユーザーによるログイン試行をクエリが可能。 SELECT EVENT_ID, CONVERT_TIMEZONE('Asia/Tokyo',EVENT_TIMESTAMP) AS JST_EVENT_TIMESTAMP, EVENT_TYPE, USER_NAME, CLIENT_IP, REPORTED_CLIENT_TYPE, REPORTED_CLIENT_VERSION, FIRST_AUTHENTICATION_FACTOR, SECOND_AUTHENTICATION_FACTOR, IS_SUCCESS, ERROR_CODE, ERROR_MESSAGE, RELATED_EVENT_ID, CONNECTION FROM SNOWFLAKE.ACCOUNT_USAGE.LOGIN_HISTORY ORDER BY EVENT_TIMESTAMP DESC ; LOGIN_HISTORY ビュー — Snowflake Documentation --- ### PostgreSQLのSQLの処理順序 date: 2022-08-31 url: https://zatoima.github.io/postgresql-sql-process-order/ tags: PostgreSQL 処理順序 WITH内のSELECT FROM WHERE GROUP BY HAVING SELECT 列に対する関数やDISTINTなど UNION、INTERSECT、EXCEPT ORDER BY LIMIT マニュアル SELECT https://www.postgresql.jp/document/14/html/sql-select.html SELECTは0個以上のテーブルから行を返します。 SELECTの一般的な処理は以下の通りです。 WITHリスト内のすべての問い合わせが計算されます。 これらは実質的には、FROMリスト内から参照可能な一時テーブルとして提供されます。 NOT MATERIALIZEDが指定された場合を除き、FROM内で2回以上参照されるWITH問い合わせは一度のみ計算されます。 (後述のWITH Clauseを参照してください。) FROMリストにある全要素が計算されます (FROMリストの要素は実テーブルか仮想テーブルのいずれかです)。 FROMリストに複数の要素が指定された場合、それらはクロス結合されます (後述のFROM Clauseを参照してください)。 WHERE句が指定された場合、条件を満たさない行は全て出力から取り除かれます (後述のWHERE Clauseを参照してください)。 GROUP BY句が指定された場合、および集約関数の呼び出しがある場合は、1つまたは複数の値が条件に合う行ごとにグループに組み合わせて出力され、また集約関数の結果が計算されます。 HAVING句が指定された場合、指定した条件を満たさないグループは取り除かれます (後述のGROUP BY ClauseとHAVING Clauseを参照してください)。 実際には、選択された各行または行グループに対して、SELECTの出力式を使用して計算した結果の行が出力されます (後述のSELECT Listを参照してください)。 SELECT DISTINCTは結果から重複行を取り除きます。 SELECT DISTINCT ONは指定した全ての式に一致する行を取り除きます。 SELECT ALLでは、重複行も含め、全ての候補行を返します(これがデフォルトです。 詳しくは、後述のDISTINCT Clauseを参照してください)。 UNION、INTERSECT、EXCEPT演算子を使用すると、複数のSELECT文の出力を1つの結果集合にまとめることができます。 UNION演算子は、両方の結果集合に存在する行と、片方の結果集合に存在する行を全て返します。 INTERSECT演算子は、両方の結果集合に存在する行を返します。 EXCEPT演算子は、最初の結果集合にあり、2番目の結果集合にない行を返します。 ALLが指定されない限り、いずれの場合も、重複する行は取り除かれます。 無意味なDISTINCTという単語を付けて、明示的に重複行を除去することを指定することができます。 SELECT自体はALLがデフォルトですが、この場合はDISTINCTがデフォルトの動作であることに注意してください。 (後述のUNION Clause、INTERSECT Clause、EXCEPT Clauseを参照してください。) ORDER BY句が指定された場合、返される行は指定した順番でソートされます。 ORDER BYが指定されない場合は、システムが計算過程で見つけた順番で行が返されます (後述のORDER BY Clauseを参照してください)。 LIMIT(またはFETCH FIRST)あるいはOFFSET句が指定された場合、SELECT文は結果行の一部分のみを返します (詳しくは、後述のLIMIT Clauseを参照してください)。 FOR UPDATE、FOR NO KEY UPDATE、FOR SHAREまたはFOR KEY SHARE句を指定すると、SELECT文は引き続き行われる更新に備えて選択行をロックします (詳しくは、後述のThe Locking Clauseを参照してください)。 余談 PostgreSQL 8.0.4とPostgreSQL 14系だとDistinctの処理順序が異なることに気がついた。なんでなんだろう。 --- ### Snowflakeのアクセス制御や権限管理 date: 2022-08-30 url: https://zatoima.github.io/snowflake-security-access-control/ tags: snowflake アクセス制御フレームワーク 任意アクセス制御(DAC): 各オブジェクトに所有者がおり、所有者はそのオブジェクトへのアクセスを許可できる ロールベースのアクセス制御(RBAC): アクセス権限がロールに割り当てられ、ロールはユーザーに割り当てられる ACCOUNTADMINについて 勘違いしていたことがあって、ACCOUNTADMINはシステムで最も強力なロールだが、OracleでいうところのSYSDBA、PostgreSQLでいうところのルートユーザだと思っていたが、実際にはスーパーユーザロールではない。 https://docs.snowflake.com/ja/user-guide/security-access-control-considerations.html#using-the-accountadmin-role ACCOUNTADMINはスーパーユーザーロール ではない ことに注意してください。このロールは、このロール、または ロール階層 の下位のロールがオブジェクトに対して十分な権限を持っている場合にのみ、アカウント内のオブジェクトの表示と管理を許可します。 https://docs.snowflake.com/ja/user-guide/security-access-control-considerations.html#managing-custom-roles カスタムロールが最初に作成されると、孤立した状態にあります。ロールに関連付けられたオブジェクト権限を使用するユーザーにロールを割り当てる必要があります。カスタムロールは、カスタムロールによって作成されたオブジェクトを管理するロールにも付与する必要があります。 デフォルトでは、ACCOUNTADMIN ロールでさえ、カスタムロールによって作成されたオブジェクトの変更やドロップはできません。カスタムロールは、ACCOUNTADMIN ロールに直接付与するか、できれば、SYSADMIN ロールを親とする階層内の別のロールに付与する必要があります。SYSADMIN ロールは ACCOUNTADMIN ロールによって管理されます。 保護可能なオブジェクト アカウント配下 ユーザ ロール データベース ウェアハウス スキーマ テーブル ビュー ステージ ストアドプロシージャ UDF等 権限の階層の継承 アクセス制御の概要 — Snowflake Documentation 実際に試してみる accountadminで作業を実施する。本来であればUSERADMINでやるべきかも… use role accountadmin; USER作成 CREATE USER IF NOT EXISTS WORKUSER PASSWORD = 'workusertest' DEFAULT_ROLE = 'PUBLIC'; ロール作成 CREATE ROLE IF NOT EXISTS WORKROLE; ロールをユーザに付与 GRANT ROLE WORKROLE TO USER WORKUSER; SHOW USER LIKE 'WORKUSER'; データベース作成 USE ROLE SYSADMIN; CREATE DATABASE WORKDB; データベースの権限付与 USE ROLE SECURITYADMIN; GRANT OWNERSHIP ON DATABASE WORKDB TO ROLE WORKROLE; GRANT OWNERSHIP ON SCHEMA WORKDB.PUBLIC TO ROLE WORKROLE; ウェアハウスの権限付与 USE ROLE SYSADMIN; CREATE WAREHOUSE WH_X_SMALL; USE ROLE SECURITYADMIN; GRANT USAGE ON WAREHOUSE WH_X_SMALL TO ROLE WORKROLE; GRANT OPERATE ON WAREHOUSE WH_X_SMALL TO ROLE WORKROLE; 作成したユーザとロールに切り替えて使っていく USE ROLE WORKROLE; USE DATABASE WORKDB; USE WAREHOUSE WH_X_SMALL; スキーマ作成 CREATE SCHEMA WORKSCHEMA; テーブル作成 OWNER等も大丈夫そう。 workuser#WH_X_SMALL@WORKDB.WORKSCHEMA>CREATE TABLE t1(a number,b VARCHAR,c VARCHAR,d number,e varchar) AS SELECT SEQ8() ,randstr(200, random()) ,randstr(300, random()) ,row_number() over (order by seq4()) ,current_timestamp FROM table(generator(rowcount => 1000)) ; +--------------------------------+ | status | |--------------------------------| | Table T1 successfully created. | +--------------------------------+ 1 Row(s) produced. Time Elapsed: 1.784s workuser#WH_X_SMALL@WORKDB.WORKSCHEMA> workuser#WH_X_SMALL@WORKDB.WORKSCHEMA>show tables; +-------------------------------+------+---------------+-------------+-------+---------+------------+------+--------+----------+----------------+----------------------+-----------------+-------------+ | created_on | name | database_name | schema_name | kind | comment | cluster_by | rows | bytes | owner | retention_time | automatic_clustering | change_tracking | is_external | |-------------------------------+------+---------------+-------------+-------+---------+------------+------+--------+----------+----------------+----------------------+-----------------+-------------| | 2022-08-25 18:18:01.195 -0700 | T1 | WORKDB | WORKSCHEMA | TABLE | | | 1000 | 505344 | WORKROLE | 1 | OFF | OFF | N | +-------------------------------+------+---------------+-------------+-------+---------+------------+------+--------+----------+----------------+----------------------+-----------------+-------------+ 1 Row(s) produced. Time Elapsed: 0.110s workuser#WH_X_SMALL@WORKDB.WORKSCHEMA> ロール階層の仕組みの確認 カスタムロールを作成するときは、最終的に高レベルの管理者ロールに割り当てられるロール階層を作成することを検討が必要ということがマニュアルに書いてある。 アクセス制御の構成 — Snowflake Documentation 現状の状態だとSYSADMINでもACCOUNTADMINでもWORKDB内のWORKSCHEMA内のT1テーブルにはアクセスできない状態になっている。 zatoima#COMPUTE_WH@(no database).(no schema)>select current_user(),current_database(), current_role(), current_warehouse(); +----------------+--------------------+----------------+---------------------+ | CURRENT_USER() | CURRENT_DATABASE() | CURRENT_ROLE() | CURRENT_WAREHOUSE() | |----------------+--------------------+----------------+---------------------| | ZATOIMA | NULL | ACCOUNTADMIN | COMPUTE_WH | +----------------+--------------------+----------------+---------------------+ zatoima#COMPUTE_WH@(no database).(no schema)>use database WORKDB; 003001 (42501): SQL access control error: Insufficient privileges to operate on database 'WORKDB' zatoima#COMPUTE_WH@(no database).(no schema)>use role WORKROLE; 003013 (42501): SQL access control error: Requested role 'WORKROLE' is not assigned to the executing user. Specify another role to activate. zatoima#COMPUTE_WH@(no database).(no schema)> sysadminにロールを付与して階層を作成 grant role WORKROLE to role sysadmin; zatoima#COMPUTE_WH@(no database).(no schema)>grant role WORKROLE to role sysadmin; +----------------------------------+ | status | |----------------------------------| | Statement executed successfully. | +----------------------------------+ 1 Row(s) produced. Time Elapsed: 0.108s zatoima#COMPUTE_WH@(no database).(no schema)> zatoima#COMPUTE_WH@(no database).(no schema)>use database WORKDB; +----------------------------------+ | status | |----------------------------------| | Statement executed successfully. | +----------------------------------+ 1 Row(s) produced. Time Elapsed: 0.148s zatoima#COMPUTE_WH@WORKDB.PUBLIC>select current_user(),current_database(), current_role(), current_warehouse(); +----------------+--------------------+----------------+---------------------+ | CURRENT_USER() | CURRENT_DATABASE() | CURRENT_ROLE() | CURRENT_WAREHOUSE() | |----------------+--------------------+----------------+---------------------| | ZATOIMA | WORKDB | ACCOUNTADMIN | COMPUTE_WH | +----------------+--------------------+----------------+---------------------+ 権限の確認 zatoima#(no warehouse)@WORKDB.PUBLIC>show grants on schema WORKSCHEMA; +-------------------------------+-----------+------------+-------------------+------------+--------------+--------------+------------+ | created_on | privilege | granted_on | name | granted_to | grantee_name | grant_option | granted_by | |-------------------------------+-----------+------------+-------------------+------------+--------------+--------------+------------| | 2022-08-25 18:17:01.660 -0700 | OWNERSHIP | SCHEMA | WORKDB.WORKSCHEMA | ROLE | WORKROLE | true | WORKROLE | +-------------------------------+-----------+------------+-------------------+------------+--------------+--------------+------------+ 1 Row(s) produced. Time Elapsed: 0.084s zatoima#(no warehouse)@WORKDB.PUBLIC> zatoima#(no warehouse)@WORKDB.PUBLIC>show grants to user workuser; +-------------------------------+----------+------------+--------------+--------------+ | created_on | role | granted_to | grantee_name | granted_by | |-------------------------------+----------+------------+--------------+--------------| | 2022-08-25 18:06:33.349 -0700 | WORKROLE | USER | WORKUSER | ACCOUNTADMIN | +-------------------------------+----------+------------+--------------+--------------+ 1 Row(s) produced. Time Elapsed: 0.088s zatoima#(no warehouse)@WORKDB.PUBLIC> zatoima#(no warehouse)@WORKDB.PUBLIC> zatoima#(no warehouse)@WORKDB.PUBLIC>show grants to role WORKROLE; +-------------------------------+-----------+------------+----------------------+------------+--------------+--------------+------------+ | created_on | privilege | granted_on | name | granted_to | grantee_name | grant_option | granted_by | |-------------------------------+-----------+------------+----------------------+------------+--------------+--------------+------------| | 2022-08-25 18:11:16.801 -0700 | OWNERSHIP | DATABASE | WORKDB | ROLE | WORKROLE | true | WORKROLE | | 2022-08-25 18:11:57.027 -0700 | OWNERSHIP | SCHEMA | WORKDB.PUBLIC | ROLE | WORKROLE | true | WORKROLE | | 2022-08-25 18:17:01.660 -0700 | OWNERSHIP | SCHEMA | WORKDB.WORKSCHEMA | ROLE | WORKROLE | true | WORKROLE | | 2022-08-25 18:18:01.317 -0700 | OWNERSHIP | TABLE | WORKDB.WORKSCHEMA.T1 | ROLE | WORKROLE | true | WORKROLE | | 2022-08-25 18:13:55.955 -0700 | OPERATE | WAREHOUSE | WH_X_SMALL | ROLE | WORKROLE | false | SYSADMIN | | 2022-08-25 18:13:42.713 -0700 | USAGE | WAREHOUSE | WH_X_SMALL | ROLE | WORKROLE | false | SYSADMIN | +-------------------------------+-----------+------------+----------------------+------------+--------------+--------------+------------+ 6 Row(s) produced. Time Elapsed: 0.089s zatoima#(no warehouse)@WORKDB.PUBLIC> カラム名 意味 created_on 権限操作によって新たにレコードが作成された日時 privilege 付与した権限の種類 granted_on 権限付与対象の種類 name 権限付与対象の名前 granted_to 非権限付与対象の種類 grantee_name 非権限付与対象の種類 grant_option 権限は操作特権付きか granted_by 権限付与の操作を行ったロール ロールを付与されたロールとユーザ一覧の表示 zatoima#COMPUTE_WH@WORKDB.WORKSCHEMA>show grants of role WORKROLE; +-------------------------------+----------+------------+--------------+--------------+ | created_on | role | granted_to | grantee_name | granted_by | |-------------------------------+----------+------------+--------------+--------------| | 2022-08-25 18:37:02.342 -0700 | WORKROLE | ROLE | SYSADMIN | ACCOUNTADMIN | | 2022-08-25 18:06:33.349 -0700 | WORKROLE | USER | WORKUSER | ACCOUNTADMIN | +-------------------------------+----------+------------+--------------+--------------+ 2 Row(s) produced. Time Elapsed: 0.411s --- ### S3(外部ステージ)からSnowflakeにデータロードする date: 2022-08-29 url: https://zatoima.github.io/snowflake-dataload-from-s3-to-snowflake/ tags: snowflake S3(外部ステージ)からSnowflakeにデータロードしてみる。 IAMポリシーの作成 sf_policyとして作成 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:GetObjectVersion", "s3:DeleteObject", "s3:DeleteObjectVersion" ], "Resource": "arn:aws:s3:::snowflake-bucket-work/*" }, { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetBucketLocation" ], "Resource": "arn:aws:s3:::snowflake-bucket-work" } ] } IAMロールの作成 sf_roleとして作成 AWSアカウントを選択 別のAWSアカウントを選択して自分の AWS アカウントID を一時的に入力 なお、後で信頼関係を変更し、Snowflakeへのアクセスを許可する “外部IDを要求する"をクリックしてダミーのIDを入力しておく 後で信頼関係を変更し、Snowflakeステージの外部 ID を指定します。AWS リソース(つまり、S3)へのアクセスをサードパーティ(つまり、Snowflake)に対して許可するには、外部 ID が必要 上記で作成したsf_policyをアタッチする Snowflake側でクラウドストレージ統合を作成 CREATE STORAGE INTEGRATION snowflake_and_s3_integration TYPE = EXTERNAL_STAGE STORAGE_PROVIDER = S3 ENABLED = TRUE STORAGE_AWS_ROLE_ARN = 'arn:aws:iam::<AWSアカウント>:role/sf_role' STORAGE_ALLOWED_LOCATIONS = ('s3://snowflake-bucket-work/') ; ※本コマンドを実行できるのはアカウント管理者( ACCOUNTADMIN ロールを持つユーザー)またはグローバル CREATE INTEGRATION 権限を持つロールのみ zatoima#COMPUTE_WH@TESTDB.PUBLIC>CREATE STORAGE INTEGRATION snowflake_and_s3_integration TYPE = EXTERNAL_STAGE STORAGE_PROVIDER = S3 ENABLED = TRUE STORAGE_AWS_ROLE_ARN = 'arn:aws:iam::<AWSアカウント>:role/sf_role' STORAGE_ALLOWED_LOCATIONS = ('s3://snowflake-bucket-work/') ; +----------------------------------------------------------------+ | status | |----------------------------------------------------------------| | Integration SNOWFLAKE_AND_S3_INTEGRATION successfully created. | +----------------------------------------------------------------+ 1 Row(s) produced. Time Elapsed: 1.015s zatoima#COMPUTE_WH@TESTDB.PUBLIC>desc integration snowflake_and_s3_integration; +---------------------------+---------------+------------------------------------------------+------------------+ | property | property_type | property_value | property_default | |---------------------------+---------------+------------------------------------------------+------------------| | ENABLED | Boolean | true | false | | STORAGE_PROVIDER | String | S3 | | | STORAGE_ALLOWED_LOCATIONS | List | s3://snowflake-bucket-work/ | [] | | STORAGE_BLOCKED_LOCATIONS | List | | [] | | STORAGE_AWS_IAM_USER_ARN | String | arn:aws:iam::xxxxxxxxx:user/qvl6-s-jpss8756 | | | STORAGE_AWS_ROLE_ARN | String | arn:aws:iam::<AWSアカウント>:role/sf_role | | | STORAGE_AWS_EXTERNAL_ID | String | <Snowflakeアカウント>_SFCRole=3_ZGmPmtzjlkklddeysL+zqym2qW8= | | | COMMENT | String | | | +---------------------------+---------------+------------------------------------------------+------------------+ 8 Row(s) produced. Time Elapsed: 0.713s zatoima#COMPUTE_WH@TESTDB.PUBLIC> STORAGE_AWS_IAM_USER_ARNとSTORAGE_AWS_EXTERNAL_IDの値を控えておく IAMロールの信頼関係の修正 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "<STORAGE_AWS_IAM_USER_ARN>" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "sts:ExternalId": "<STORAGE_AWS_EXTERNAL_ID>" } } } ] } 外部ステージの作成 CREATE STAGE s3_ext_stage STORAGE_INTEGRATION = snowflake_and_s3_integration URL = 's3://snowflake-bucket-work/'; zatoima#COMPUTE_WH@TESTDB.PUBLIC>CREATE STAGE s3_ext_stage STORAGE_INTEGRATION = snowflake_and_s3_integration URL = 's3://snowflake-bucket-work/'; +-----------------------------------------------+ | status | |-----------------------------------------------| | Stage area S3_EXT_STAGE successfully created. | +-----------------------------------------------+ zatoima#COMPUTE_WH@TESTDB.PUBLIC>show stages; +-------------------------------+--------------+---------------+-------------+-----------------------------+-----------------+--------------------+--------------+---------+----------------+----------+-------+----------------------+------------------------------+ | created_on | name | database_name | schema_name | url | has_credentials | has_encryption_key | owner | comment | region | type | cloud | notification_channel | storage_integration | |-------------------------------+--------------+---------------+-------------+-----------------------------+-----------------+--------------------+--------------+---------+----------------+----------+-------+----------------------+------------------------------| | 2022-08-23 22:45:45.523 -0700 | S3_EXT_STAGE | TESTDB | PUBLIC | s3://snowflake-bucket-work/ | N | N | ACCOUNTADMIN | | ap-northeast-1 | EXTERNAL | AWS | NULL | SNOWFLAKE_AND_S3_INTEGRATION | +-------------------------------+--------------+---------------+-------------+-----------------------------+-----------------+--------------------+--------------+---------+----------------+----------+-------+----------------------+------------------------------+ 1 Row(s) produced. Time Elapsed: 0.098s データロード copy into t1 from @s3_ext_stage pattern='test.csv'; zatoima#COMPUTE_WH@TESTDB.PUBLIC>copy into t1 from @s3_ext_stage pattern='test.csv'; +-------------------------------------+--------+-------------+-------------+-------------+-------------+-------------+------------------+-----------------------+-------------------------+ | file | status | rows_parsed | rows_loaded | error_limit | errors_seen | first_error | first_error_line | first_error_character | first_error_column_name | |-------------------------------------+--------+-------------+-------------+-------------+-------------+-------------+------------------+-----------------------+-------------------------| | s3://snowflake-bucket-work/test.csv | LOADED | 10 | 10 | 1 | 0 | NULL | NULL | NULL | NULL | +-------------------------------------+--------+-------------+-------------+-------------+-------------+-------------+------------------+-----------------------+-------------------------+ 1 Row(s) produced. Time Elapsed: 2.675s zatoima#COMPUTE_WH@TESTDB.PUBLIC>select * from t1; +---+--------+--------+----+-------------------------------+ | A | B | C | D | E | |---+--------+--------+----+-------------------------------| | 0 | 111111 | 222222 | 1 | 2022-08-23 22:47:44.214 -0700 | | 1 | 111111 | 222222 | 2 | 2022-08-23 22:47:44.214 -0700 | | 2 | 111111 | 222222 | 3 | 2022-08-23 22:47:44.214 -0700 | | 3 | 111111 | 222222 | 4 | 2022-08-23 22:47:44.214 -0700 | | 4 | 111111 | 222222 | 5 | 2022-08-23 22:47:44.214 -0700 | | 5 | 111111 | 222222 | 6 | 2022-08-23 22:47:44.214 -0700 | | 6 | 111111 | 222222 | 7 | 2022-08-23 22:47:44.214 -0700 | | 7 | 111111 | 222222 | 8 | 2022-08-23 22:47:44.214 -0700 | | 8 | 111111 | 222222 | 9 | 2022-08-23 22:47:44.214 -0700 | | 9 | 111111 | 222222 | 10 | 2022-08-23 22:47:44.214 -0700 | +---+--------+--------+----+-------------------------------+ 10 Row(s) produced. Time Elapsed: 0.198s zatoima#COMPUTE_WH@TESTDB.PUBLIC> ロード時のオプション ON_ERRORオプション CONTINUE エラーが見つかった場合は、ファイルのロードを続行します。エラーが見つかった行はロードされません。 SKIP_FILE エラーが見つかった場合はファイルをスキップします。 SKIP_FILE_数値 ファイル内で見つかったエラー行の数が指定された数以上の場合は、ファイルをスキップします。 SKIP_FILE_数値% ファイル内で見つかったエラー行の割合が指定された割合を超えた場合は、ファイルをスキップします。 ABORT_STATEMENT データファイルでエラーが見つかった場合は、ロード操作を中止します。 COPY INTO <テーブル> — Snowflake Documentation データアンロード copy into @s3_ext_stage/unload/ from t1; デフォルトでは圧縮された状態でアンロードされる。 参照 オプション1:Amazon S3にアクセスするためのSnowflakeストレージ統合の構成 — Snowflake Documentation Amazon S3へのアンロード — Snowflake Documentation --- ### SnowPro Core認定の試験ガイド対策 date: 2022-08-27 url: https://zatoima.github.io/snowflake-snowpro-core-certification-study/ tags: snowflake SnowPro Core 認定は対策本や対策サイトみたいなものはないのでここは基本通り試験ガイドに沿ってのマニュアルやネット情報の参照、検証作業で行くしかないと踏んだのでメモします。 SnowPro Core 認定試験ガイド Snowflake 認定資格 | Snowflake 【スノーフレイク】 https://www.snowflake.com/certifications/?lang=ja 1.0 分野:アカウントとセキュリティ 1.1 Snowflakeアカウントを管理する方法について説明する。 アカウント使用状況 アカウントの使用 — Snowflake Documentation 情報スキーマ INFORMATION_SCHEMA アカウントで作成されたオブジェクトに関する広範なメタデータ情報を提供するシステム定義のビューとテーブル関数のセットで構成 Snowflake Information Schema — Snowflake Documentation 1.2 セキュリティの原則の概要を説明する。 多要素認証(MFA) Duo MobileでMFA設定する コンソール、SnowSQL (CLI クライアント)、JDBCドライバなどで認証が必要となる 多要素認証(MFA) — Snowflake Documentation データ暗号化 エンドツーエンド暗号化 AES256暗号化 エンドツーエンド暗号化(E2EE)は、データを保護する方法であり、保存データまたはSnowflakeとの間で転送中のデータを暗号化する CloudHSMを使った階層型キーモデル 自動ローテーション Snowflakeが管理するキーすべては、30日以上経過するとSnowflakeによって自動的にローテーションされる。 Tri-Secret Secure Snowflakeアカウントをホストするクラウドプロバイダープラットフォームで、Snowflakeが管理するキーと顧客が管理するキーを組み合わせて、Snowflakeデータを保護するための複合マスターキーを作成する機能 利用のためにはサポートへの連絡が必要 Business Criticalエディション以上 データ暗号化 — Snowflake Documentation Snowflakeのデータ保護(暗号化)についてお勉強してみた #SnowflakeDB | DevelopersIO ネットワークセキュリティとポリシー 継続的なデータ保護 継続的なデータ保護 — Snowflake Documentation ネットワークポリシー アクセスを許可または制限するためのネットワークポリシー IP許可、制限リスト アクセス制御 Snowflakeのアクセス制御 — Snowflake Documentation 任意アクセス制御(DAC): 各オブジェクトに所有者がおり、所有者はそのオブジェクトへのアクセスを許可できます。 ロールベースのアクセス制御(RBAC): アクセス権限がロールに割り当てられ、ロールはユーザーに割り当てられます。 システム定義のロール ロール名 役割 説明 SYSADMIN アカウントでウェアハウスとデータベース(およびその他のオブジェクト)を作成する権限を持つロール ORGADMIN 組織レベルで運用を管理するロール ・組織内に アカウントを作成 できます。 ・組織内のすべてのアカウント(SHOW ORGANIZATION ACCOUNTS を使用)と、組織で有効になっているすべてのリージョン(SHOW REGIONS を使用)を表示できます。 ・組織全体の 使用情報 を表示できます。 ACCOUNTADMIN SYSADMIN および SECURITYADMIN システム定義のロールをカプセル化するロール システムの最上位のロールであり、アカウント内の限られた/制御された数のユーザーにのみ付与する必要がある ・アカウントでウェアハウスとデータベース(およびその他のオブジェクト)を作成する権限を持つロール ・オブジェクトの付与をグローバルに管理し、ユーザーとロールを作成、モニター、管理できるロール SECURITYADMIN オブジェクトの付与をグローバルに管理し、ユーザーとロールを作成、モニター、管理できるロール ・MANAGE GRANTS セキュリティ権限が付与されており、付与の取り消しを含め、あらゆる付与を変更できます。 ・システムロール階層を介して USERADMIN ロールの権限を継承します(つまり、 USERADMIN ロールを SECURITYADMIN に付与)。 USERADMIN ユーザーとロールの管理のみに専用のロール ・CREATE USERおよびCREATE ROLEのセキュリティ権限が付与されています。 ・アカウントにユーザーとロールを作成できます。 PUBLIC アカウント内のすべてのユーザーおよびすべてのロールに自動的に付与される疑似ロール 通常、このロールは、明示的なアクセス制御が不要で、すべてのユーザーがアクセスに関して平等であると見なされる場合に使用されます。 フェデレーション認証 フェデレーション認証の概要と SSO — Snowflake Documentation SnowflakeでSAML認証を使用したシングルサインオン(SSO)を設定する(Auth0編) #SnowflakeDB | DevelopersIO シングルサインオン(SSO) AzureADやOkta等を使ってSSOを設定できる Snowflakeに対してAzure ADアカウントによるシングルサインオンの設定 - Qiita 外部 OAuth 用Microsoft Azure AD の構成 — Snowflake Documentation 外部 OAuth 用Oktaの構成 — Snowflake Documentation 1.3 Snowflakeで使用されるエンティティとロールを定義する。 権限を付与および取り消す方法の概要を説明する CREATE ROLE test_role; GRANT USAGE ON DATABASE citibike TO ROLE test_role; GRANT USAGE ON DATABASE weather TO ROLE test_role; revoke role aaaa from role vvvv; ロールの階層と権限の継承について説明する ロール アクセス制御の概要 — Snowflake Documentation 上のアクセス制御と同じなはず 1.4 Snowflakeの各エディションに関連するセキュリティ機能について説明する。 データマスキング ダイナミックデータマスキング Snowflakeのマスキング機能を試してみた Snowflakeが提供するガバナンス機能のまとめ | DevelopersIO 列レベルのセキュリティについて — Snowflake Documentation1.5 Snowflakeのデータガバナンス機能の概要を説明する データマスキング 上記と同様 アカウント使用状況ビュー アカウントの使用 — Snowflake Documentation 外部トークン化 カラム(列)ベースのセキュリティ機能で、対象カラムの値をtokenizationする Third-party製品の関数が必要 外部トークン化 — Snowflake Documentation 2.0 分野:仮想ウェアハウス 2.1 コンピューティングの原則の概要を説明する。 クレジット使用状況と請求 コストについて — Snowflake Documentation Snowflakeでクレジットの使用状況を確認してみた 〜ウェブインターフェイス編〜 | DevelopersIO 同時実行 ウェアハウスの概要 — Snowflake Documentation 各クエリのサイズと複雑さによって決定する クエリを処理するのに十分なリソースがウェアハウスにない場合、クエリはキューに入れられ、保留中のリソースは実行中の他のクエリが完b了すると利用可能になる 同時実行を上げるためにはマルチクラスタ化する(Enterprise Edition以上が必要) キャッシング # キャッシュ名 キャッシュ対象 使用可能なユーザー 保存レイヤー 有効期間 1 結果キャッシュ クエリの結果 クエリが実行された同じロールのすべてのユーザー Snowflake 24時間 2 メタデータキャッシュ テーブルに関する情報 すべてのユーザー Snowflake 常に 3 データキャッシュ クエリ結果のファイルヘッダとカラムデータ 同じ仮想ウェアハウスを実行したユーザー ウェアハウス(SSD) ウェアハウスの稼働中 注意事項 結果キャッシュ https://docs.snowflake.com/ja/user-guide/querying-persisted-results.html#retrieval-optimization 通常、次の条件の すべて が満たされる場合、クエリ結果が再利用されます。 新しいクエリは、以前に実行したクエリと構文的に一致する。 クエリには、実行時に評価する必要のある関数が含まれていない(例: CURRENT_TIMESTAMP() および UUID_STRING())。 CURRENT_DATE() 関数はこのルールの例外です。CURRENT_DATE() は実行時に評価されますが、 CURRENT_DATE() を使用するクエリは、クエリ再利用機能を引き続き使用できます。 クエリには、 ユーザー定義関数(UDFs) または 外部関数 が含まれていない。 クエリ結果に寄与するテーブルデータが変更されていない。 以前のクエリの永続化された結果が引き続き利用可能である。 キャッシュされた結果にアクセスするロールには、必要な権限がある。 クエリが SELECT クエリの場合、クエリを実行するロールには、キャッシュされたクエリで使用されるすべてのテーブルに必要なアクセス権限が必要です。 クエリが SHOW クエリの場合、クエリを実行するロールは、キャッシュされた結果を生成したロールと一致する必要があります。 結果の生成方法に影響する構成オプションが変更されていない。 テーブル内にある他のデータ変更によって、テーブルのマイクロパーティションが変更されていない(例: 再クラスタ化または統合化)。 これらの条件をすべて満たしても、Snowflakeがクエリ結果を再利用することは 保証されません。 Snowflakeの3種類のキャッシュについてお勉強してみた #SnowflakeDB | DevelopersIO 保存済みのクエリ結果の使用 — Snowflake Documentation Snowflakeにてクエリ実行時にキャッシュを利用しないようにパラメータを設定する方法 - Qiita Snowflakeの3つのキャッシュ 2.2 仮想ウェアハウスのベストプラクティスを説明する。 スケールアップとスケールアウト タイプの変更とマルチクラスタ 仮想ウェアハウスのタイプ Tシャツサイズと同じ 管理/監視 ウェアハウス負荷の監視 — Snowflake Documentation Snowflakeでウェアハウスの負荷監視を試してみた | DevelopersIO 3.0 分野:データ移動 3.1 データのロードに使用されるさまざまなコマンドと、それらをいつ使用する必要があるかについての概要を説明する。 COPY COPY INTO <テーブル> — Snowflake Documentation 一括データロード時 COPY INTO xxxx ~~ INSERT ??? INSERT INTO xxxx SELECT ~~? PUT GET PUTとGETは内部ステージとデータのやり取りをする際に使用 VALIDATE VALIDATE — Snowflake Documentation COPY INTO <テーブル> コマンドの過去の実行でロードされたファイルを検証し、最初のエラーだけでなくロード中に発生したすべてのエラーを返す関数 select * from table(validate(t1, job_id => '_last')); 3.2 連続データロード方法と比較してバルクを定義する。 COPY 一括データロード時 COPY INTO xxxx ~~ Snowpipe Snowflakeの継続的なデータロード「Snowpipe」を試してみた | DevelopersIO Snowflakeでデータパイプラインを作ってみた | DevelopersIO 3.3 データをロードするときに考慮すべきベストプラクティスを定義する。 ファイルサイズ フォルダー データのロードの概要 データロード機能の概要 データロードに関する考慮事項 3.4 Snowflakeからローカルストレージまたはクラウドストレージの場所にデータをアンロードする方法の概要を説明する。 Snowflakeからデータをアンロードする際にサポートされているファイル形式を定義する データのアンロードの準備 — Snowflake Documentation JSON、Parquet 区切り(CSV、TSV など) 常に UTF-8を使用してエンコード データをアンロードするときに考慮すべきベストプラクティスを定義する データのアンロードの概要 データのアンロード機能の概要 データのアンロードに関する考慮事項 3.5 半構造化データの操作方法とロード方法を説明する。 サポートされているファイル形式 JSON、Avro、 ORC、Parquet、XML 半構造化データの概要 — Snowflake Documentation VARIANT列 半構造化データのクエリ — Snowflake Documentation ネストされた構造のフラット化 select value:name::string as "Customer Name", value:address::string as "Address" from car_sales , lateral flatten(input => src:customer); select src:customer[0].name, src:vehicle[0].price from car_sales order by 1; 4.0 分野:パフォーマンス管理 4.1 ストレージでのSnowflakeパフォーマンス管理のベストプラクティスの概要を説明する。 クラスタリング クラスタリングキーとクラスタ化されたテーブル — Snowflake Documentation Snowflake側でもクラスタリングすることができるが、ユーザ側でも特定のキーをクラスタリングキーと指定することでクラスタリングが可能。 すべてのテーブルで推奨されるものではない。追加のコストが必要となる。 コストに関係なく、可能な限り最速の応答時間が必要。 クエリパフォーマンスの向上により、テーブルのクラスター化と維持に必要なクレジットが相殺される。 マテリアライズドビュー 結果の自動メンテナンスによる マテリアライズドビュー Enterprise Edition以上の機能 検索最適化 Enterprise Edition以上の機能 大きなテーブルにおける選択的な検索クエリのパフォーマンスを向上させる機能 テーブルサイズが 100GB 以上ある 非クラスター化テーブルである メインクラスターキー以外の列で頻繁に検索される 数十秒実行されるクエリを実行する クエリフィルターでアクセスされる列の少なくとも1つに、10万〜20万以上の個別の値がある 等価述語<列名> = <定数> やINを使用する述語を利用している 検索最適化サービスの使用 — Snowflake Documentation Snowflakeの検索最適化サービス(Search Optimization Service)を試してみた | DevelopersIO 4.2 仮想ウェアハウスでのSnowflakeパフォーマンス管理のベストプラクティスの概要を説明する。 クエリのパフォーマンスと分析 クエリプロファイル クエリプロファイルを使用したクエリの分析 — Snowflake Documentation クエリ履歴 履歴ページを使用してクエリを監視 — Snowflake Documentation コンソール上からは過去14日間に実行されたすべてのクエリの詳細を表示して詳細を確認 QUERY_HISTORY ビュー — Snowflake Documentation 過去365日間(1年間)以内のさまざまなディメンション(時間範囲、セッション、ユーザー、ウェアハウスなど)によりSnowflakeクエリ履歴をクエリできます。 SQLの最適化 キャッシング メタデータキャッシュ クエリ結果キャッシュ 24時間保存。データが変更されていない限り有効 クエリ結果キャッシュの無効化 ALTER SESSION SET USE_CACHED_RESULT = FALSE; 5.0 分野:Snowflakeの概要とアーキテクチャ 5.1 Snowflakeのクラウドデータプラットフォームの主要コンポーネントの概要を説明する。 データ型 オプティマイザー 継続的なデータ保護 クローニング キャッシングのタイプ ウェブインターフェイス(UI) データクラウド/データ共有/ Data Marketplace/Data Exchange 5.2 Snowflakeデータ共有機能の概要を説明する。 アカウントタイプ Data MarketplaceとData Exchange アクセス制御オプション 共有 5.3 Snowflakeが従来のウェアハウスソリューションとどのように異なるかを説明する。 エラスティックストレージ エラスティックコンピューティング アカウント管理 5.4 利用可能なさまざまなエディションと、各エディションに関連する機能の概要を説明する。 料金 機能 Snowflake Edition — Snowflake Documentation 料金体系 | Snowflake 【スノーフレイク】 5.5 Snowflakeのパートナーエコシステムを特定する クラウドパートナー コネクタ 5.6 Snowflakeの3つの異なるレイヤーの目的の概要を説明し、定義する。 ストレージレイヤー コンピューティングレイヤー クラウドサービスレイヤー 5.7 Snowflakeのカタログとオブジェクトの概要を説明する。 データベース スキーマ テーブルタイプ ビュータイプ データ型 外部関数 6.0 分野:ストレージと保護 6.1 Snowflakeストレージの概念の概要を説明する。 マイクロパーティション メタデータ型 クラスタリング データストレージ ステージタイプ ファイル形式 ストレージモニタリング 6.2 Snowflakeによる継続的なデータ保護の概要を説明する。 Time Travel SnowflakeのTime Travel | my opinion is my own Fail Safe SnowflakeのFail-safe | my opinion is my own データ暗号化 https://docs.snowflake.com/ja/user-guide/security-encryption.html https://docs.snowflake.com/ja/user-guide/data-load-s3-encrypt.html https://dev.classmethod.jp/articles/snowflake-data-encryption/ クローニング https://docs.snowflake.com/ja/user-guide/object-clone.html https://dev.classmethod.jp/articles/snowflake-advent-calendar-2019-24/ https://dk521123.hatenablog.com/entry/2021/11/27/134934 https://note.com/datasaber/n/n2609995fa5cb https://note.com/datasaber/n/ne31a7ac0f6b2 追記 (8/27 追記)なんとか合格できました。 --- ### DynamoDBからAurora PostgreSQLへのデータレプリケーション環境を作成する date: 2022-08-25 url: https://zatoima.github.io/aws-dynamodb-to-aurora-postgresql-replication/ tags: AWS, Aurora, DynamoDB はじめに Amazon DynamoDB からのデータストリームを AWS Lambda と Amazon Kinesis Firehose を活用して Amazon Aurora に格納する | Amazon Web Services ブログ https://aws.amazon.com/jp/blogs/news/how-to-stream-data-from-amazon-dynamodb-aws-lambda-amazon-kinesis-firehose/ 2017年のこの記事を参考にしつつ、色々と実現方式も変わっているのでイチから環境構築等を行うメモ。Glue Elastic ViewsがGAになれば置き換わるかもしれない。単純なレプリケーションのみであることに注意。更新、削除の場合はAuroraへのロード方式を変更する必要がある。 DynamoDBからAuroraへのデータレプリケーション方式について DynamoDBからAuroraへの連携についてはいくつかパターンがあるので適切な方式を選択した方が良い。下記参考。 AWS DMS と Amazon Kinesis Data Firehose を利用した Aurora PostgreSQL データベースへのストリームデータのロード | Amazon Web Services ブログ Amazon DynamoDB ストリームを使用して、順序付けされたデータをアプリケーション間でレプリケーションする方法 | Amazon Web Services ブログ Amazon Kinesis Firehose Data Transformation with AWS Lambda | AWS Compute Blog 今回は①DynamoDB->②DynamoDB Streams-> ③Amazon Kinesis Data Stream-> ④Amazon Kinesis Firehose->⑤Lambda->⑥S3->⑦Lambda->⑧Auroraとなる。 S3に配置する前段階の⑤のLambdaでストリーミングで流れてくるJSONをCSVにデータ変換を行い、⑥のS3のイベント通知で⑦のLambdaを発火させ、Aurora PostgreSQLにデータロードを行う。 ⑤Lambdaを挟まずとも④のKinesis FirehoseからS3に対してはデータを送れるが、CSV形式で格納し、データロードをしたかったので⑤のLamdbaを挟むことにした。 ①DynamoDB aws dynamodb create-table \ --table-name dynamotest \ --attribute-definitions \ AttributeName=id,AttributeType=S \ AttributeName=datetime,AttributeType=S \ --key-schema AttributeName=id,KeyType=HASH AttributeName=datetime,KeyType=RANGE \ --billing-mode PAY_PER_REQUEST ②DynamoDB Streams データストリームを有効化する ③Amazon Kinesis Data Stream オンデマンド、もしくはシャード数の指定。データ保持期間等を事前に決めておく。 ④Amazon Kinesis Firehose バックアップの有無やバッファサイズやインターバルは適宜変更した方が良さそう。 Transform source records with AWS LambdaでLamdbaを指定する。 ⑤Lambda 下記ブログの通り DynamoDBからkinesis firehose経由でS3に出力時にJSON形式からCSV形式に変換するLamdba用のPythonスクリプト | my opinion is my own 👋 ⑥S3 特に変わったところはなし ⑦Lambda、⑧Aurora 下記ブログの通り S3へのファイルのPUTを検知してLamdbaからAurora PostgreSQLのテーブルへCSV形式のデータをロード | my opinion is my own 👋 Lambdaからawslambda-psycopg2を使用してAurora PostgreSQLに接続 | my opinion is my own 👋 --- ### SnowflakeのTime Travel date: 2022-08-25 url: https://zatoima.github.io/snowflake-timetravel-summary/ tags: snowflake SnowPro Core 認定試験ガイドの6.2向けの勉強メモ Snowflake 認定資格 | Snowflake 【スノーフレイク】 https://www.snowflake.com/certifications/?lang=ja 6.2 Snowflakeによる継続的なデータ保護の概要を説明する。 Time Travel Fail Safe データ暗号化 クローニング Time Travelの概要 テーブル、スキーマ、データベース、について定義された期間の間の任意の時点で履歴データにアクセスできる機能。 通常、テーブルをDROPした場合、バックアップから戻すことが必要となるが、Time Travel機能を使用することで簡単に復元することが出来る テーブルだけではなく、スキーマやデータベース単位と広い論理範囲で戻すことが出来る エディションによる戻せる期間の差異 Standard:最大1日 Enterprise以上:最大90日 テーブルの種類による戻せる期間の差異 Transient及びTemporaryテーブルは最大1日 設定方法 設定値の確認 SHOW PARAMETERS like '%DATA_RETENTION_TIME_IN_DAYS%' in account; アカウントレベルの設定(※危険) ALTER ACCOUNT SET DATA_RETENTION_TIME_IN_DAYS=5; テーブル単位の設定 CREATE TABLE my_table (c1 int) SET DATA_RETENTION_TIME_IN_DAYS=90 ALTER TABLE my_table SET DATA_RETENTION_TIME_IN_DAYS=30 Time Travelの実行方法 復元、クエリ、クローンの3種類がある 復元 -- データベースの復元 UNDROP DATABASE <name>; -- スキーマの復元 UNDROP SCHEMA <name>; -- テーブルの復元 UNDROP TABLE <name>; クエリ 標準時からマイナス7時間とした上で、2015年5月1日16時20分時点のmy_tableのデータを取得する SELECT * FROM my_table AT(timestamp => 'Fri, 01 May 2015 16:20:00 -0700'::timestamp_tz); 10分前の時点のmy_tableのデータを取得する。offsetには秒単位で入れるため、「60秒×10」で10分を表す SELECT * FROM my_table AT((offset => -60*10); 指定したクエリIDのクエリが実行される前の状態の、my_tableのデータを取得する SELECT * FROM my_table BEFORE(statement => '<クエリID>'); クローニング 指定されたタイムスタンプで表される日付と時刻のテーブルのクローンを作成 create table restored_table clone my_table at(timestamp => 'Sat, 09 May 2015 01:01:00 +0300'::timestamp_tz); 現在時刻の1時間前に存在していたスキーマとそのすべてのオブジェクトのクローンを作成 create schema restored_schema clone my_schema at(offset => -3600); 指定されたステートメントの完了前に存在していたデータベースとそのすべてのオブジェクトのクローンを作成 create database restored_db clone my_db before(statement => '8e5d0ca9-005e-44e6-b858-a8f5b37c5726'); Time Travelの使用量について TABLE_STORAGE_METRICS ビュー — Snowflake Documentation 上記ビューから確認が可能 select TABLE_CATALOG, TABLE_NAME, ((ACTIVE_BYTES / 1024) / 1024) / 1024 as storage_usage_gb, ((TIME_TRAVEL_BYTES / 1024) / 1024) / 1024 as timetravel_usage_gb from "INFORMATION_SCHEMA".table_storage_metrics where TABLE_NAME in('T1') ; 参考 Time Travelの理解と使用 — Snowflake Documentation Time TravelおよびFail-safeのストレージコスト — Snowflake Documentation Snowflakeのタイムトラベル関連でよく使いそうなコマンドを試してみた #SnowflakeDB | DevelopersIO Snowflakeのタイムトラベル機能であの頃(の状態のデータ)に戻ろう | DevelopersIO --- ### SnowflakeのFail-safe date: 2022-08-20 url: https://zatoima.github.io/snowflake-failsafe-summary/ tags: snowflake SnowPro Core 認定試験ガイドの6.2向けの勉強メモ Snowflake 認定資格 | Snowflake 【スノーフレイク】 https://www.snowflake.com/certifications/?lang=ja 6.2 Snowflakeによる継続的なデータ保護の概要を説明する。 Time Travel Fail Safe データ暗号化 クローニング 概要 Time Travel保持期間が終了した直後にFail-safeにデータが移行される。Snowflakeによって履歴データを回復できる可能性のある期間(構成不可能)は7日間となる。“可能性のある期間"というメッセージがマニュアルにある通り、ベストエフォート方式で提供されるデータ回復サービスとなる。 設定方法 特になし Time Travelのようにエディションによって条件が分かれているとかではない 使用量の確認 select TABLE_CATALOG, TABLE_NAME, ((ACTIVE_BYTES / 1024) / 1024) / 1024 as storage_usage_gb, ((FAILSAFE_BYTES / 1024) / 1024) / 1024 as failsage_usage_gb, ((TIME_TRAVEL_BYTES / 1024) / 1024) / 1024 as timetravel_usage_gb from "INFORMATION_SCHEMA".table_storage_metrics where TABLE_NAME in('T1') ; 使用量はコンソールからも確認できる 注意事項 完了するまでに数時間から数日かかる場合がある サポートに連絡して復旧してもらう必要がある ベストエフォート方式で提供されるデータ回復サービス Fail-safeは、Time Travel保持期間が終了した後に履歴データにアクセスする手段としては提供されていません いつのまにかFailsafe用の領域が溜まりがちなのでオペレーションやテーブルの種類に注意が必要だな、と思った。何も考えずにいるとテーブル作成→テストデータ生成→DropでFailsafe用の領域がたくさんになってしまうという未来が見える。 参照 Fail-safeの理解と表示 — Snowflake Documentation --- ### Dockerのエラー対応(docker Got permission denied~) date: 2022-08-06 url: https://zatoima.github.io/docker-error-permission-denied/ tags: Docker エラー内容 [ec2-user@bastin ~]$ docker run -e MF_ID -e MF_PASS -e ALPHAVANTAGE_API_KEY -it public.ecr.aws/h3b4x6x6/mfstockupdater:1d0c9ea docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/create": dial unix /var/run/docker.sock: connect: permission denied. See 'docker run --help'. 対応内容 sudo gpasswd -a $(whoami) docker sudo chgrp docker /var/run/docker.sock sudo service docker restart [ec2-user@bastin ~]$ sudo gpasswd -a $(whoami) docker Adding user ec2-user to group docker [ec2-user@bastin ~]$ sudo chgrp docker /var/run/docker.sock [ec2-user@bastin ~]$ sudo service docker restart Redirecting to /bin/systemctl restart docker.service --- ### Aurora PostgreSQLでpg_settingsをCSVで出力する date: 2022-07-31 url: https://zatoima.github.io/aws-aurora-postgresql-pg_settings-csv-output/ tags: AWS, Aurora コマンド 区切り文字をコンマ(,)でなく、"|“としている psql -h auroraserverlessv2.cluster-xxxxxx.ap-northeast-1.rds.amazonaws.com -c "select * from pg_settings;" -U postgres -d postgres -A -F"|" > pg_settings.csv --- ### LambdaをVPCで使用する際のENI数 date: 2022-07-24 url: https://zatoima.github.io/aws-lamdba-vpc-eni-number-use/ tags: AWS, Lambda [発表] Lambda 関数が VPC 環境で改善されます | Amazon Web Services ブログ https://aws.amazon.com/jp/blogs/news/announcing-improved-vpc-networking-for-aws-lambda-functions/ 以前: 今: https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/foundation-networking.html?utm_source=pocket_mylist ENI の管理 Lambda は、関数実行ロールのアクセス許可を使用して、ネットワークインターフェイスを作成および管理します。アカウントで VPC 対応関数に一意のサブネットとセキュリティグループの組み合わせを定義すると、Lambda は Hyperplane ENI を作成します。Lambda は、同じサブネットとセキュリティグループの組み合わせを使用するアカウントの他の VPC 対応関数に Hyperplane ENI を再利用します。 同じ Hyperplane ENI を使用できる Lambda 関数の数にクォータはありません。ただし、各 Hyperplane ENI は最大 65,000 個の接続/ポートをサポートします。接続数が 65,000 を超えると、Lambda は新しい Hyperplane ENI を作成して、追加の接続を提供します。 関数設定を更新して別の VPC にアクセスすると、Lambda は以前の VPC の Hyperplane ENI への接続を終了します。新しい VPC への接続を更新するプロセスには、数分かかる場合があります。この間、関数への呼び出しは以前の VPC を使用し続けます。更新が完了すると、新しい VPC で Hyperplane ENI を使用して新しい呼び出しが開始されます。この時点で、Lambda 関数は以前の VPC に接続されなくなります。 --- ### Aurora PostgreSQLにパッチを適用した際のダウンタイムログ date: 2022-07-20 url: https://zatoima.github.io/aws-aurora-patch-apply-downtime-log/ tags: AWS, Aurora パッチの中身に依存するので参考までに。この時のパッチ適用の実質的なダウンタイムは約7秒だった。 スクリプト import psycopg2 import psycopg2.extras import time import datetime for i in range(20000): try: dt_now = datetime.datetime.now() conn = psycopg2.connect("host=auroraserverlessv2.cluster-cm678nkt5thr.ap-northeast-1.rds.amazonaws.com port=5432 dbname=postgres user=postgres password=postgres") cur = conn.cursor() cur.execute("insert into zdptest (time) values (current_timestamp)") print(dt_now) time.sleep(1) conn.commit() cur.close() conn.close() except: pass ログ 2022-06-28 13:52:53 UTC::@:[31196]:LOG: starting PostgreSQL 13.6 on aarch64-unknown-linux-gnu, compiled by aarch64-unknown-linux-gnu-gcc (GCC) 7.4.0, 64-bit 2022-06-28 13:52:53 UTC::@:[31196]:LOG: listening on IPv4 address "0.0.0.0", port 5432 2022-06-28 13:52:53 UTC::@:[31196]:LOG: listening on IPv6 address "::", port 5432 2022-06-28 13:52:53 UTC::@:[31196]:LOG: listening on Unix socket "/tmp/.s.PGSQL.5432" 2022-06-28 13:52:53 UTC::@:[31196]:LOG: Waiting for runtime initialization complete... 2022-06-28 13:52:54 UTC:[local]:rdsadmin@rdsadmin:[31354]:FATAL: the database system is starting up 2022-06-28 13:52:54 UTC::@:[31352]:LOG: database system was interrupted; last known up at 2022-06-28 13:52:19 UTC 2022-06-28 13:52:54 UTC:10.0.1.31(34296):postgres@postgres:[31353]:FATAL: the database system is starting up 2022-06-28 13:52:54 UTC:10.0.1.31(34298):postgres@postgres:[31368]:FATAL: the database system is starting up 2022-06-28 13:52:54 UTC:10.0.1.31(34300):postgres@postgres:[31382]:FATAL: the database system is starting up 2022-06-28 13:52:54 UTC:10.0.1.31(34302):postgres@postgres:[31386]:FATAL: the database system is starting up 2022-06-28 13:52:54 UTC:10.0.1.31(34304):postgres@postgres:[31402]:FATAL: the database system is starting up 2022-06-28 13:52:54 UTC:10.0.1.31(34306):postgres@postgres:[31440]:FATAL: the database system is starting up 2022-06-28 13:52:54 UTC:10.0.1.31(34308):postgres@postgres:[31448]:FATAL: the database system is starting up 2022-06-28 13:52:54 UTC:10.0.1.31(34310):postgres@postgres:[31457]:FATAL: the database system is starting up 2022-06-28 13:52:55 UTC:10.0.1.31(34312):postgres@postgres:[31467]:FATAL: the database system is starting up 2022-06-28 13:52:55 UTC:10.0.1.31(34314):postgres@postgres:[31478]:FATAL: the database system is starting up 2022-06-28 13:52:55 UTC::@:[31196]:LOG: database system is ready to accept connections 2022-06-28 13:55:10 UTC::@:[31196]:LOG: received SIGHUP, reloading configuration files 2022-06-28 13:55:10 UTC::@:[31196]:LOG: skipping missing configuration file "/rdsdbdata/config/recovery.conf" 2022-06-28 13:55:10 UTC::@:[31196]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2022-06-28 13:55:10 UTC::@:[31196]:LOG: parameter "unix_socket_permissions" cannot be changed without restarting the server 2022-06-28 13:55:10 UTC::@:[31196]:LOG: parameter "shared_buffers" cannot be changed without restarting the server 2022-06-28 13:55:10 UTC::@:[31196]:LOG: parameter "apg_critical_insights_enabled" changed to "on" 2022-06-28 13:55:10 UTC::@:[31196]:LOG: configuration file "/rdsdbdata/config/postgresql.conf" contains errors; unaffected changes were applied 2022-06-28 13:55:10 UTC::@:[31490]:LOG: skipping missing configuration file "/rdsdbdata/config/recovery.conf" 2022-06-28 13:55:10 UTC::@:[31486]:LOG: skipping missing configuration file "/rdsdbdata/config/recovery.conf" 2022-06-28 13:55:10 UTC::@:[31486]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2022-06-28 13:55:10 UTC::@:[31490]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2022-06-28 13:55:10 UTC::@:[31262]:LOG: skipping missing configuration file "/rdsdbdata/config/recovery.conf" 2022-06-28 13:55:10 UTC::@:[31262]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2022-06-28 13:55:10 UTC::@:[31489]:LOG: skipping missing configuration file "/rdsdbdata/config/recovery.conf" 2022-06-28 13:55:10 UTC::@:[31489]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2022-06-28 13:55:10 UTC::@:[31226]:LOG: skipping missing configuration file "/rdsdbdata/config/recovery.conf" 2022-06-28 13:55:10 UTC::@:[31226]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2022-06-28 13:55:10 UTC::@:[31485]:LOG: skipping missing configuration file "/rdsdbdata/config/recovery.conf" 2022-06-28 13:55:10 UTC::@:[31485]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2022-06-28 13:55:10 UTC::@:[31487]:LOG: skipping missing configuration file "/rdsdbdata/config/recovery.conf" 2022-06-28 13:55:10 UTC::@:[31487]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2022-06-28 13:55:10 UTC::@:[31492]:LOG: skipping missing configuration file "/rdsdbdata/config/recovery.conf" 2022-06-28 13:55:10 UTC::@:[31492]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2022-06-28 13:55:10 UTC::@:[31488]:LOG: skipping missing configuration file "/rdsdbdata/config/recovery.conf" 2022-06-28 13:55:10 UTC::@:[31488]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2022-06-28 13:55:10 UTC:10.0.1.31(34600):postgres@postgres:[11434]:LOG: skipping missing configuration file "/rdsdbdata/config/recovery.conf" 2022-06-28 13:55:10 UTC:10.0.1.31(34600):postgres@postgres:[11434]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2022-06-28 13:55:30 UTC::@:[31196]:LOG: received SIGHUP, reloading configuration files 2022-06-28 13:55:30 UTC::@:[31196]:LOG: skipping missing configuration file "/rdsdbdata/config/recovery.conf" 2022-06-28 13:55:30 UTC::@:[31196]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2022-06-28 13:55:30 UTC::@:[31196]:LOG: parameter "unix_socket_permissions" cannot be changed without restarting the server 2022-06-28 13:55:30 UTC::@:[31196]:LOG: parameter "shared_buffers" cannot be changed without restarting the server 2022-06-28 13:55:30 UTC::@:[31196]:LOG: parameter "rds.enable_buffer_pin_conflict_forking" changed to "on" 2022-06-28 13:55:30 UTC::@:[31196]:LOG: parameter "rds.apg_space_reclaim_thread_enabled" changed to "on" 2022-06-28 13:55:30 UTC::@:[31196]:LOG: configuration file "/rdsdbdata/config/postgresql.conf" contains errors; unaffected changes were applied 2022-06-28 13:55:30 UTC::@:[31262]:LOG: skipping missing configuration file "/rdsdbdata/config/recovery.conf" 2022-06-28 13:55:30 UTC::@:[31262]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2022-06-28 13:55:30 UTC::@:[31226]:LOG: skipping missing configuration file "/rdsdbdata/config/recovery.conf" 2022-06-28 13:55:30 UTC::@:[31226]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2022-06-28 13:55:30 UTC::@:[31487]:LOG: skipping missing configuration file "/rdsdbdata/config/recovery.conf" 2022-06-28 13:55:30 UTC::@:[31487]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2022-06-28 13:55:30 UTC::@:[31488]:LOG: skipping missing configuration file "/rdsdbdata/config/recovery.conf" 2022-06-28 13:55:30 UTC::@:[31488]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2022-06-28 13:55:30 UTC::@:[31492]:LOG: skipping missing configuration file "/rdsdbdata/config/recovery.conf" 2022-06-28 13:55:30 UTC::@:[31492]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2022-06-28 13:55:30 UTC::@:[31489]:LOG: skipping missing configuration file "/rdsdbdata/config/recovery.conf" 2022-06-28 13:55:30 UTC::@:[31489]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2022-06-28 13:55:30 UTC::@:[31485]:LOG: skipping missing configuration file "/rdsdbdata/config/recovery.conf" 2022-06-28 13:55:30 UTC::@:[31485]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2022-06-28 13:55:30 UTC::@:[31486]:LOG: skipping missing configuration file "/rdsdbdata/config/recovery.conf" 2022-06-28 13:55:30 UTC::@:[31486]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2022-06-28 13:55:30 UTC::@:[31490]:LOG: skipping missing configuration file "/rdsdbdata/config/recovery.conf" 2022-06-28 13:55:30 UTC::@:[31490]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2022-06-28 13:55:30 UTC:10.0.1.31(34640):postgres@postgres:[12957]:LOG: skipping missing configuration file "/rdsdbdata/config/recovery.conf" 2022-06-28 13:55:30 UTC:10.0.1.31(34640):postgres@postgres:[12957]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" テーブル 321 | 2022-06-28 13:52:39.452956 322 | 2022-06-28 13:52:40.483377 323 | 2022-06-28 13:52:41.516449 324 | 2022-06-28 13:52:42.54735 325 | 2022-06-28 13:52:43.579139 326 | 2022-06-28 13:52:44.610785 327 | 2022-06-28 13:52:45.642509 328 | 2022-06-28 13:52:46.673966 329 | 2022-06-28 13:52:47.705797 330 | 2022-06-28 13:52:48.738429 ★←約10秒弱書き込めていない 331 | 2022-06-28 13:52:55.153238 332 | 2022-06-28 13:52:56.194006 333 | 2022-06-28 13:52:57.228373 334 | 2022-06-28 13:52:58.263974 335 | 2022-06-28 13:52:59.317474 336 | 2022-06-28 13:53:00.347215 337 | 2022-06-28 13:53:01.379734 338 | 2022-06-28 13:53:02.417656 339 | 2022-06-28 13:53:03.451107 340 | 2022-06-28 13:53:04.487402 341 | 2022-06-28 13:53:05.522603 342 | 2022-06-28 13:53:06.554656 Auroraクラスタ側のイベント情報 --- ### snowsqlのインストール date: 2022-07-15 url: https://zatoima.github.io/snowflake-snowsql-install-howto/ tags: Snowflake リポジトリ https://sfc-repo.snowflakecomputing.com/snowsql/bootstrap/1.2/linux_x86_64/index.html rpmのダウンロード [ec2-user@bastin ~]$ wget https://sfc-repo.snowflakecomputing.com/snowsql/bootstrap/1.2/linux_x86_64/snowflake-snowsql-1.2.9-1.x86_64.rpm --2022-07-11 21:25:48-- https://sfc-repo.snowflakecomputing.com/snowsql/bootstrap/1.2/linux_x86_64/snowflake-snowsql-1.2.9-1.x86_64.rpm Resolving sfc-repo.snowflakecomputing.com (sfc-repo.snowflakecomputing.com)... 65.9.42.106, 65.9.42.8, 65.9.42.36, ... Connecting to sfc-repo.snowflakecomputing.com (sfc-repo.snowflakecomputing.com)|65.9.42.106|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 25164112 (24M) [binary/octet-stream] Saving to: ‘snowflake-snowsql-1.2.9-1.x86_64.rpm’ 100%[==================================================================================================================================================================================================>] 25,164,112 20.0MB/s in 1.2s 2022-07-11 21:25:50 (20.0 MB/s) - ‘snowflake-snowsql-1.2.9-1.x86_64.rpm’ saved [25164112/25164112] [ec2-user@bastin ~]$ ls -l snowflake-snowsql-1.2.9-1.x86_64.rpm -rw-rw-r-- 1 ec2-user ec2-user 25164112 Aug 7 2020 snowflake-snowsql-1.2.9-1.x86_64.rpm rpmからインストール [ec2-user@bastin ~]$ sudo rpm -ivh snowflake-snowsql-1.2.9-1.x86_64.rpm Preparing... ################################# [100%] Updating / installing... 1:snowflake-snowsql-1.2.9-1 ################################# [100%] [ec2-user@bastin ~]$ snowsql -v Version: 1.2.9 ヘルプ [ec2-user@bastin ~]$ snowsql --help Usage: snowsql [OPTIONS] Options: -a, --accountname TEXT Name assigned to your Snowflake account. If you are not on us-west-2 or AWS deployement, append the region and platform to the end, e.g., <account>.<region> or <account>.<region>.<platform>Honors $SNOWSQL_ACCOUNT. -u, --username TEXT Username to connect to Snowflake. Honors $SNOWSQL_USER. -d, --dbname TEXT Database to use. Honors $SNOWSQL_DATABASE. -s, --schemaname TEXT Schema in the database to use. Honors $SNOWSQL_SCHEMA. -r, --rolename TEXT Role name to use. Honors $SNOWSQL_ROLE. -w, --warehouse TEXT Warehouse to use. Honors $SNOWSQL_WAREHOUSE. -h, --host TEXT Host address for the connection. Honors $SNOWSQL_HOST. -p, --port INTEGER Port number for the connection. Honors $SNOWSQL_PORT. --region TEXT (DEPRECATED) Append the region or any sub domains before snowflakecomputing.com to the end of accountname parameter after a dot. e.g., accountname=<account>.<region> -m, --mfa-passcode TEXT Token to use for multi-factor authentication (MFA) --mfa-passcode-in-password Appends the MFA passcode to the end of the password. --abort-detached-query Aborts a query if the connection between the client and server is lost. By default, it won't abort even if the connection is lost. --probe-connection Test connectivity to Snowflake. This option is mainly used to print out the TLS/SSL certificate chain. --proxy-host TEXT (DEPRECATED. Use HTTPS_PROXY and HTTP_PROXY environment variables.) Proxy server hostname. Honors $SNOWSQL_PROXY_HOST. --proxy-port INTEGER (DEPRECATED. Use HTTPS_PROXY and HTTP_PROXY environment variables.) Proxy server port number. Honors $SNOWSQL_PROXY_PORT. --proxy-user TEXT (DEPRECATED. Use HTTPS_PROXY and HTTP_PROXY environment variables.) Proxy server username. Honors $SNOWSQL_PROXY_USER. Set $SNOWSQL_PROXY_PWD for the proxy server password. --authenticator TEXT Authenticator: 'snowflake', 'externalbrowser' (to use any IdP and a web browser), 'oauth', or https://<your_okta_account_name>.okta.com (to use Okta natively). -v, --version Shows the current SnowSQL version, or uses a specific version if provided as a value. --noup Disables auto-upgrade for this run. If no version is specified for -v, the latest version in ~/.snowsql/ is used. -D, --variable TEXT Sets a variable to be referred by &<var>. -D tablename=CENUSTRACKONE or --variable db_key=$DB_KEY -o, --option TEXT Set SnowSQL options. See the options reference in the Snowflake documentation. -f, --filename PATH File to execute. -q, --query TEXT Query to execute. --config PATH Path and name of the SnowSQL configuration file. By default, ~/.snowsql/config. -P, --prompt Forces a password prompt. By default, $SNOWSQL_PWD is used to set the password. -M, --mfa-prompt Forces a prompt for the second token for MFA. -c, --connection TEXT Named set of connection parameters to use. --single-transaction Connects with autocommit disabled. Wraps BEGIN/COMMIT around statements to execute them as a single transaction, ensuring all commands complete successfully or no change is applied. --private-key-path PATH Path to private key file in PEM format used for key pair authentication. Private key file is required to be encrypted and passphrase is required to be specified in environment variable $SNOWSQL_PRIVATE_KEY_PASSPHRASE -U, --upgrade Force upgrade of SnowSQL to the latest version. -K, --client-session-keep-alive Keep the session active indefinitely, even if there is no activity from the user.. --disable-request-pooling Disable request pooling. This can help speed up connection failover --token TEXT The token to be used with oauth authentication method -?, --help Show this message and exit. 参考 SnowSQL のインストール — Snowflake Documentation https://docs.snowflake.com/ja/user-guide/snowsql-install-config.html --- ### AWS Direct Connect参考資料メモ date: 2022-07-11 url: https://zatoima.github.io/aws-direct-connect-documents/ tags: AWS 最高にわかりやすかった。毎回マニュアルかBlackbelt見ないと理解出来ないのでメモしておく。[@kamogashira](https://twitter.com/kamogashira)さんのツイートから。 https://twitter.com/kamogashira/status/1589182761440792576?s=12&t=KUYcQm1RyjKtp8WCm3QJVQ --- ### GISの殴り書きメモ date: 2022-07-11 url: https://zatoima.github.io/other-geographic-information-system-desc/ tags: Other 用語のメモ。GISは奥が深い…GIS屋という職業が存在するわけだ GIS Geographic Information System 民間のWeb地図には著作権の壁がある オープンな地図データ OpenStreetMap(OSM) https://www.openstreetmap.org 国土地理院の地理院地図 https://maps.gsi.go.jp/ 位置情報を使用した有名なWebサービス https://flightradars24.info/ja/ https://www.marinetraffic.com/ GISのデータ構造 ベクター形式 点、線、多角形 ポイント(点) ライン(線) ポリゴン(面) ラスター形式 行と列の格子状(グリッド状)に並んだセル(ピクセル)で構成されるデータ 地図と組み合わせてデータを表示したい場合に使われる 降水量や気温、標高データなど アドレスマッチング 逆GEO ジオコーダー https://qiita.com/uhey22e/items/69285a14b4476dc73664 --- ### Kinesis Data Streamsのホットシャードを見つけるツール date: 2022-07-08 url: https://zatoima.github.io/aws-kinesis-hot-shard-advisor/ tags: AWS, Kinesis https://github.com/awslabs/kinesis-hot-shard-advisor --- ### Aurora PostgreSQLでPostGIS(位置情報)を使用する date: 2022-07-05 url: https://zatoima.github.io/aws-aurora-postgresql-postgis/ tags: AWS, Aurora, PostgreSQL 事前準備 参考資料 PostGIS 拡張機能を使用した空間データの管理 - Amazon Relational Database Service 拡張機能の有効化 CREATE EXTENSION postgis; CREATE EXTENSION fuzzystrmatch; CREATE EXTENSION postgis_tiger_geocoder; CREATE EXTENSION postgis_topology; postgres=> CREATE EXTENSION postgis; CREATE EXTENSION postgres=> CREATE EXTENSION fuzzystrmatch; CREATE EXTENSION postgres=> CREATE EXTENSION postgis_tiger_geocoder; CREATE EXTENSION postgres=> CREATE EXTENSION postgis_topology; CREATE EXTENSION postgres=> postgres=> postgres=> \dx List of installed extensions Name | Version | Schema | Description ------------------------+---------+------------+------------------------------------------------------------------------ aws_commons | 1.2 | public | Common data types across AWS services aws_s3 | 1.1 | public | AWS S3 extension for importing data from S3 fuzzystrmatch | 1.1 | public | determine similarities and distance between strings pg_buffercache | 1.3 | public | examine the shared buffer cache pg_stat_statements | 1.8 | public | track planning and execution statistics of all SQL statements executed plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language postgis | 3.1.5 | public | PostGIS geometry and geography spatial types and functions postgis_tiger_geocoder | 3.1.5 | tiger | PostGIS tiger geocoder and reverse geocoder postgis_topology | 3.1.5 | topology | PostGIS topology spatial types and functions (9 rows) postgres=> バージョン確認 postgres=> select * from postgis_version(); postgis_version --------------------------------------- 3.1 USE_GEOS=1 USE_PROJ=1 USE_STATS=1 (1 row) 権限変更 ALTER SCHEMA tiger OWNER TO rds_superuser; ALTER SCHEMA tiger_data OWNER TO rds_superuser; ALTER SCHEMA topology OWNER TO rds_superuser; postgres=> \dn List of schemas Name | Owner -------------+--------------- aws_commons | rds_superuser aws_s3 | rds_superuser public | postgres tiger | rdsadmin tiger_data | rdsadmin topology | rdsadmin (6 rows) postgres=> ALTER SCHEMA tiger OWNER TO rds_superuser; ALTER SCHEMA postgres=> ALTER SCHEMA tiger_data OWNER TO rds_superuser; ALTER SCHEMA postgres=> ALTER SCHEMA topology OWNER TO rds_superuser; ALTER SCHEMA postgres=> \dn List of schemas Name | Owner -------------+--------------- aws_commons | rds_superuser aws_s3 | rds_superuser public | postgres tiger | rds_superuser tiger_data | rds_superuser topology | rds_superuser (6 rows) postgres=> rds_superuser ロールにオブジェクトの所有権を転送 ALTER文を生成してくれるので実行。 CREATE FUNCTION exec(text) returns text language plpgsql volatile AS $f$ BEGIN EXECUTE $1; RETURN $1; END; $f$; SELECT exec('ALTER TABLE ' || quote_ident(s.nspname) || '.' || quote_ident(s.relname) || ' OWNER TO rds_superuser;') FROM ( SELECT nspname, relname FROM pg_class c JOIN pg_namespace n ON (c.relnamespace = n.oid) WHERE nspname in ('tiger','topology') AND relkind IN ('r','S','v') ORDER BY relkind = 'S') s; postgres=> CREATE FUNCTION exec(text) returns text language plpgsql volatile AS $f$ BEGIN EXECUTE $1; RETURN $1; END; $f$; CREATE FUNCTION postgres=> postgres=> SELECT exec('ALTER TABLE ' || quote_ident(s.nspname) || '.' || quote_ident(s.relname) || ' OWNER TO rds_superuser;') postgres-> FROM ( postgres(> SELECT nspname, relname postgres(> FROM pg_class c JOIN pg_namespace n ON (c.relnamespace = n.oid) postgres(> WHERE nspname in ('tiger','topology') AND postgres(> relkind IN ('r','S','v') ORDER BY relkind = 'S') postgres-> s; exec -------------------------------------------------------------------- ALTER TABLE tiger.loader_variables OWNER TO rds_superuser; ALTER TABLE tiger.loader_lookuptables OWNER TO rds_superuser; ALTER TABLE tiger.zip_lookup OWNER TO rds_superuser; ALTER TABLE tiger.tract OWNER TO rds_superuser; ALTER TABLE tiger.geocode_settings_default OWNER TO rds_superuser; ALTER TABLE tiger.tabblock OWNER TO rds_superuser; ALTER TABLE tiger.county OWNER TO rds_superuser; ALTER TABLE tiger.bg OWNER TO rds_superuser; ALTER TABLE tiger.direction_lookup OWNER TO rds_superuser; ALTER TABLE tiger.pagc_gaz OWNER TO rds_superuser; ALTER TABLE tiger.geocode_settings OWNER TO rds_superuser; ALTER TABLE tiger.pagc_lex OWNER TO rds_superuser; ALTER TABLE tiger.state OWNER TO rds_superuser; ALTER TABLE tiger.pagc_rules OWNER TO rds_superuser; ALTER TABLE tiger.secondary_unit_lookup OWNER TO rds_superuser; ALTER TABLE topology.topology OWNER TO rds_superuser; ALTER TABLE topology.layer OWNER TO rds_superuser; ALTER TABLE tiger.place OWNER TO rds_superuser; ALTER TABLE tiger.zip_state OWNER TO rds_superuser; ALTER TABLE tiger.zip_state_loc OWNER TO rds_superuser; ALTER TABLE tiger.state_lookup OWNER TO rds_superuser; ALTER TABLE tiger.cousub OWNER TO rds_superuser; ALTER TABLE tiger.street_type_lookup OWNER TO rds_superuser; ALTER TABLE tiger.edges OWNER TO rds_superuser; ALTER TABLE tiger.place_lookup OWNER TO rds_superuser; ALTER TABLE tiger.addrfeat OWNER TO rds_superuser; ALTER TABLE tiger.county_lookup OWNER TO rds_superuser; ALTER TABLE tiger.faces OWNER TO rds_superuser; ALTER TABLE tiger.countysub_lookup OWNER TO rds_superuser; ALTER TABLE tiger.featnames OWNER TO rds_superuser; ALTER TABLE tiger.zip_lookup_all OWNER TO rds_superuser; ALTER TABLE tiger.addr OWNER TO rds_superuser; ALTER TABLE tiger.zip_lookup_base OWNER TO rds_superuser; ALTER TABLE tiger.zcta5 OWNER TO rds_superuser; ALTER TABLE tiger.tabblock20 OWNER TO rds_superuser; ALTER TABLE tiger.loader_platform OWNER TO rds_superuser; ALTER TABLE tiger.pagc_lex_id_seq OWNER TO rds_superuser; ALTER TABLE tiger.county_gid_seq OWNER TO rds_superuser; ALTER TABLE tiger.state_gid_seq OWNER TO rds_superuser; ALTER TABLE tiger.place_gid_seq OWNER TO rds_superuser; ALTER TABLE tiger.cousub_gid_seq OWNER TO rds_superuser; ALTER TABLE tiger.edges_gid_seq OWNER TO rds_superuser; ALTER TABLE tiger.addrfeat_gid_seq OWNER TO rds_superuser; ALTER TABLE tiger.faces_gid_seq OWNER TO rds_superuser; ALTER TABLE tiger.featnames_gid_seq OWNER TO rds_superuser; ALTER TABLE tiger.addr_gid_seq OWNER TO rds_superuser; ALTER TABLE tiger.zcta5_gid_seq OWNER TO rds_superuser; ALTER TABLE tiger.tract_gid_seq OWNER TO rds_superuser; ALTER TABLE tiger.tabblock_gid_seq OWNER TO rds_superuser; ALTER TABLE tiger.bg_gid_seq OWNER TO rds_superuser; ALTER TABLE tiger.pagc_gaz_id_seq OWNER TO rds_superuser; ALTER TABLE tiger.pagc_rules_id_seq OWNER TO rds_superuser; ALTER TABLE topology.topology_id_seq OWNER TO rds_superuser; (53 rows) PostGISを使用して実行 テスト① postgres=> CREATE TABLE t1 (id int primary key); CREATE TABLE postgres=> postgres=> SELECT addGeometryColumn('t1', 'p1', 4326, 'POINT', 2); addgeometrycolumn ------------------------------------------- public.t1.p1 SRID:4326 TYPE:POINT DIMS:2 (1 row) postgres=> \d t1 Table "public.t1" Column | Type | Collation | Nullable | Default --------+----------------------+-----------+----------+--------- id | integer | | not null | p1 | geometry(Point,4326) | | | Indexes: "t1_pkey" PRIMARY KEY, btree (id) postgres=> postgres=> INSERT INTO t1 VALUES (1, ST_GeomFromText('POINT(139 36)',4326)); INSERT 0 1 postgres=> SELECT id, ST_AsText(p1) FROM t1; id | st_astext ----+--------------- 1 | POINT(139 36) (1 row) postgres=> postgres=> postgres=> SELECT id, postgres-> ST_Transform(p1, 32654) <-> postgres-> ST_Transform(ST_GeomFromText('POINT(139.11234 35.998765)', 4326), 32654) postgres-> AS distance FROM t1 ORDER BY distance ; id | distance ----+-------------------- 1 | 10129.774748121428 (1 row) テスト② テーブル作成 CREATE TABLE geo_sample ( id integer PRIMARY KEY, name varchar(255), geom geometry(POINT, 4326) ); データ投入 INSERT INTO geo_sample VALUES (1, '表参道駅', ST_GeomFromText('POINT(139.712288 35.664342)',4326)); INSERT INTO geo_sample VALUES (2, '青山一丁目駅', ST_GeomFromText('POINT(139.725146 35.672963)',4326)); INSERT INTO geo_sample VALUES (3, '赤坂駅', ST_GeomFromText('POINT(139.7365419 35.671949)',4326)); 2点間の距離を求める: ST_Distance() select a.name || ' to ' || b.name, ST_Distance( ST_Transform(a.geom, 2163), ST_Transform(b.geom, 2163)) from geo_sample a, geo_sample b where a.name = '表参道駅' and b.name = '青山一丁目駅'; postgres=> select a.name || ' to ' || b.name, postgres-> ST_Distance( postgres(> ST_Transform(a.geom, 2163), postgres(> ST_Transform(b.geom, 2163)) postgres-> from geo_sample a, geo_sample b postgres-> where a.name = '表参道駅' and b.name = '青山一丁目駅'; ?column? | st_distance --------------------------+-------------------- 表参道駅 to 青山一丁目駅 | 1184.3450716154289 (1 row) PgAdminで確認 簡単にPgAdminを使用してさっくり確認も出来る。 テスト③ CREATE TABLE geotable ( id SERIAL NOT NULL PRIMARY KEY, name varchar (255) NOT NULL, geom geography(POINT, 4326) NOT NULL ); -- データの挿入 INSERT INTO geotable (name, geom) VALUES ('上野駅', ST_GeographyFromText('SRID=4326;POINT(139.777254 35.713768)')), ('西郷隆盛像', ST_GeographyFromText('SRID=4326;POINT(139.774029 35.711846)')), ('上野の森美術館', ST_GeographyFromText('SRID=4326;POINT(139.774744 35.712737)')), ('不忍池弁財天', ST_GeographyFromText('SRID=4326;POINT(139.770872 35.712351)')), ('野口英世博士像', ST_GeographyFromText('SRID=4326;POINT(139.775696 35.716293)')), ('国立西洋美術館', ST_GeographyFromText('SRID=4326;POINT(139.775803 35.71542)')), ('国立科学博物館', ST_GeographyFromText('SRID=4326;POINT(139.776544 35.716319)')), ('東京都美術館', ST_GeographyFromText('SRID=4326;POINT(139.772776 35.717186)')), ('東京国立博物館', ST_GeographyFromText('SRID=4326;POINT(139.776462 35.718883)')), ('花やしき', ST_GeographyFromText('SRID=4326;POINT(139.794547 35.71528)')), ('雷門', ST_GeographyFromText('SRID=4326;POINT(139.792692 35.710635)')); -- 空間インデックスの作成 CREATE INDEX gist_geotable on geotable USING GIST (geom); SELECT name, ST_AsText(geom), ST_Distance('SRID=4326;POINT(139.777254 35.713768)', geom) as dist FROM geotable WHERE ST_DWithin(geom, ST_GeographyFromText('SRID=4326;POINT(139.777254 35.713768)'), 500.0) ORDER BY dist; postgres=> SELECT postgres-> name, postgres-> ST_AsText(geom), postgres-> ST_Distance('SRID=4326;POINT(139.777254 35.713768)', geom) as dist postgres-> FROM geotable postgres-> WHERE ST_DWithin(geom, ST_GeographyFromText('SRID=4326;POINT(139.777254 35.713768)'), 500.0) postgres-> ORDER BY dist; name | st_astext | dist ----------------+-----------------------------+-------------- 上野駅 | POINT(139.777254 35.713768) | 0 国立西洋美術館 | POINT(139.775803 35.71542) | 225.46891659 上野の森美術館 | POINT(139.774744 35.712737) | 254.30812788 国立科学博物館 | POINT(139.776544 35.716319) | 290.24270722 野口英世博士像 | POINT(139.775696 35.716293) | 313.62968599 西郷隆盛像 | POINT(139.774029 35.711846) | 361.44255611 (6 rows) PostGIS(地理情報システムを実現するための拡張モジュール) https://www.sraoss.co.jp/tech-blog/pgsql/postgis/ 位置情報を可視化しよう![PostGIS入門]|kota|note --- ### Redshiftの内部アーキテクチャに関する資料 date: 2022-07-05 url: https://zatoima.github.io/aws-redshift-internal-re-invented/ tags: AWS, Redshift Redshiftの進化。こんな内部アーキテクチャが外部向けの公開されているなんて。 – Amazon Redshift re-invented - Amazon Science https://www.amazon.science/publications/amazon-redshift-re-invented --- ### S3イベントの発火漏れは2022年時点では発生しない date: 2022-07-01 url: https://zatoima.github.io/aws-s3-event-missing/ tags: AWS, S3 結論 結論を表題に書いた通りだが、S3イベントの発火漏れはもはや発生しない。 以前のドキュメントにはS3イベント通知は欠損する可能性があり、ドキュメントにもその旨が記載されているが、2022年時点では下記の通り発生しない。 https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/NotificationHowTo.html Amazon S3 イベント通知は、少なくとも 1 回配信されるように設計されています。通常、イベント通知は数秒で配信されますが、1 分以上かかる場合もあります。 少し古い記事だとS3イベントの発火漏れが起きうるとのの記載があり、この仕様改善(?)を書かれた記事があまり無かったのでメモ。 https://dev.classmethod.jp/articles/s3-event-notification-vs-eventbridge-event-processing-overflow-rate/ https://qiita.com/kkimura/items/92833436349d8fc5ad29 --- ### アカウントを跨いだ際のS3へのアクセスについて date: 2022-06-28 url: https://zatoima.github.io/aws-s3-access-iam-bucket-policy/ tags: AWS S3のバケットポリシーでハマったので、S3へのアクセスを許可するPrincipalの設定を整理する | DevelopersIO https://dev.classmethod.jp/articles/summarize-principal-settings-in-s3-bucket-policy/?utm_source=pocket_mylist IAMユーザーとS3が同じアカウントか IAMポリシー バケットポリシー(ユーザーArn指定) バケットポリシー(AWSアカウント指定) 備考 同じ いずれか必要 いずれか必要 - IAMポリシーまたはバケットポリシーのどちらかで許可されていればアクセス可能 異なる 許可必須 いずれか必要 いずれか必要 IAMポリシーとバケットポリシー両方の許可が必要。バケットポリシーはユーザーArnでもAWSアカウント指定でもOK --- ### DynamoDBからKinesis Streamsに流したレコードの中身を見る date: 2022-06-24 url: https://zatoima.github.io/aws-dynamodb-replication-record-kinesis/ tags: AWS, DynamoDB テーブル定義 aws dynamodb create-table \ --table-name dynamotest \ --attribute-definitions \ AttributeName=id,AttributeType=S \ AttributeName=datetime,AttributeType=S \ --key-schema AttributeName=id,KeyType=HASH AttributeName=datetime,KeyType=RANGE \ --billing-mode PAY_PER_REQUEST DynamoDBのKinesis Data Streamsの設定 テーブル新規挿入&更新 2件INSERT、2件UPDATE(このとき全て同じキーをアップデートする) aws dynamodb put-item --table-name kinesis-test --item "{ \"datetime\": { \"S\": \"aaaaaaaaaaa\" }, \"id\": { \"S\": \"aaaaaaaaaaa\" } }" aws dynamodb put-item --table-name kinesis-test --item "{ \"datetime\": { \"S\": \"bbbbbbbbbbb\" }, \"id\": { \"S\": \"bbbbbbbbbbb\" } }" aws dynamodb update-item --table-name kinesis-test --key "{ \"datetime\": { \"S\": \"aaaaaaaaaaa\" }, \"id\": { \"S\": \"aaaaaaaaaaa\" } }" --attribute-updates '{"ccc": {"Value": {"S":"sample text"}}}' aws dynamodb update-item --table-name kinesis-test --key "{ \"datetime\": { \"S\": \"aaaaaaaaaaa\" }, \"id\": { \"S\": \"aaaaaaaaaaa\" } }" --attribute-updates '{"ccc": {"Value": {"S":"gogogogo"}}}' aws dynamodb scan --table-name kinesis-test 結果 base64 デコードするとデータの中身も見れる。 https://www.base64decode.org/ オンデマンドのKinesis Data Streamsにデータを流していて、シャード0とシャード1にはデータ無し、シャード2には1件、シャード3には3件入っている。DynamoDB側のキーが同じアップデートに対しては同じシャードに入ってくる。 [ec2-user@bastin ~]$ SHARD_ITERATOR=$(aws kinesis get-shard-iterator --shard-id shardId-000000000002 --shard-iterator-type TRIM_HORIZON --stream-name ddb-stream-test --query 'ShardIterator') [ec2-user@bastin ~]$ aws kinesis get-records --shard-iterator $SHARD_ITERATOR { "Records": [ { "SequenceNumber": "49630754920274845572843534141988045219888124757907865634", "ApproximateArrivalTimestamp": "2022-06-24T14:23:08.513000+09:00", "Data": "eyJhd3NSZWdpb24iOiJhcC1ub3J0aGVhc3QtMSIsImV2ZW50SUQiOiJlYjFiOWM2Ni03MTY5LTQzNjQtYjY0Mi1hYzU2ZjAxY2JhZjAiLCJldmVudE5hbWUiOiJJTlNFUlQiLCJ1c2VySWRlbnRpdHkiOm51bGwsInJlY29yZEZvcm1hdCI6ImFwcGxpY2F0aW9uL2pzb24iLCJ0YWJsZU5hbWUiOiJraW5lc2lzLXRlc3QiLCJkeW5hbW9kYiI6eyJBcHByb3hpbWF0ZUNyZWF0aW9uRGF0ZVRpbWUiOjE2NTYwNDgxODc5MjIsIktleXMiOnsiaWQiOnsiUyI6ImJiYmJiYmJiYmJiIn0sImRhdGV0aW1lIjp7IlMiOiJiYmJiYmJiYmJiYiJ9fSwiTmV3SW1hZ2UiOnsiaWQiOnsiUyI6ImJiYmJiYmJiYmJiIn0sImRhdGV0aW1lIjp7IlMiOiJiYmJiYmJiYmJiYiJ9fSwiU2l6ZUJ5dGVzIjo2NH0sImV2ZW50U291cmNlIjoiYXdzOmR5bmFtb2RiIn0=", "PartitionKey": "49DE9F3D57177739BC4A3A6E32350613" } ], "NextShardIterator": "AAAAAAAAAAFAzXEe3Y9ICjI+/VTUw038RKRC5PNLwKueAvRHUdllhOoWHRyUnc4ReetrVMFOdWcng4Qe2czh/zhnWallAJmQC+yqO7kEY8ZgGFw8lfBAgrnbp4dMnZtuoEAgC66TxKmQhFieDQB5pprN5fhfMq1Ep0BVsqsr1SgXpv4aH1U5fsbKHpuGbiUOleZyDyigqofl0k2tFFERdwwNcXX5YEM81iK9JrAEoiQp4Fl5b7Y7pA==", "MillisBehindLatest": 0 } [ec2-user@bastin ~]$ [ec2-user@bastin ~]$ SHARD_ITERATOR=$(aws kinesis get-shard-iterator --shard-id shardId-000000000003 --shard-iterator-type TRIM_HORIZON --stream-name ddb-stream-test --query 'ShardIterator') [ec2-user@bastin ~]$ aws kinesis get-records --shard-iterator $SHARD_ITERATOR { "Records": [ { "SequenceNumber": "49630754920297146318042064765128372012341141379089432626", "ApproximateArrivalTimestamp": "2022-06-24T14:18:58.894000+09:00", "Data": "eyJhd3NSZWdpb24iOiJhcC1ub3J0aGVhc3QtMSIsImV2ZW50SUQiOiJjMWViYmM3NS00Mjk3LTQwNzQtYWJlMC0yZmQ2OTMwNjk3YzUiLCJldmVudE5hbWUiOiJJTlNFUlQiLCJ1c2VySWRlbnRpdHkiOm51bGwsInJlY29yZEZvcm1hdCI6ImFwcGxpY2F0aW9uL2pzb24iLCJ0YWJsZU5hbWUiOiJraW5lc2lzLXRlc3QiLCJkeW5hbW9kYiI6eyJBcHByb3hpbWF0ZUNyZWF0aW9uRGF0ZVRpbWUiOjE2NTYwNDc5Mzg3MzksIktleXMiOnsiaWQiOnsiUyI6ImFhYWFhYWFhYWFhIn0sImRhdGV0aW1lIjp7IlMiOiJhYWFhYWFhYWFhYSJ9fSwiTmV3SW1hZ2UiOnsiaWQiOnsiUyI6ImFhYWFhYWFhYWFhIn0sImRhdGV0aW1lIjp7IlMiOiJhYWFhYWFhYWFhYSJ9fSwiU2l6ZUJ5dGVzIjo2NH0sImV2ZW50U291cmNlIjoiYXdzOmR5bmFtb2RiIn0=", "PartitionKey": "D1174FF2F6189C4B8B91C573346158AD" }, { "SequenceNumber": "49630754920297146318042064765135625567258871347896385586", "ApproximateArrivalTimestamp": "2022-06-24T14:29:13.673000+09:00", "Data": "eyJhd3NSZWdpb24iOiJhcC1ub3J0aGVhc3QtMSIsImV2ZW50SUQiOiJmMWRjZmYxZS1hNzg0LTQzMWItYmI2MS00Mjc0YmU5NjM1YWQiLCJldmVudE5hbWUiOiJNT0RJRlkiLCJ1c2VySWRlbnRpdHkiOm51bGwsInJlY29yZEZvcm1hdCI6ImFwcGxpY2F0aW9uL2pzb24iLCJ0YWJsZU5hbWUiOiJraW5lc2lzLXRlc3QiLCJkeW5hbW9kYiI6eyJBcHByb3hpbWF0ZUNyZWF0aW9uRGF0ZVRpbWUiOjE2NTYwNDg1NTM1NTcsIktleXMiOnsiaWQiOnsiUyI6ImFhYWFhYWFhYWFhIn0sImRhdGV0aW1lIjp7IlMiOiJhYWFhYWFhYWFhYSJ9fSwiTmV3SW1hZ2UiOnsiaWQiOnsiUyI6ImFhYWFhYWFhYWFhIn0sImRhdGV0aW1lIjp7IlMiOiJhYWFhYWFhYWFhYSJ9LCJjY2MiOnsiUyI6InNhbXBsZSB0ZXh0In19LCJPbGRJbWFnZSI6eyJpZCI6eyJTIjoiYWFhYWFhYWFhYWEifSwiZGF0ZXRpbWUiOnsiUyI6ImFhYWFhYWFhYWFhIn19LCJTaXplQnl0ZXMiOjExMH0sImV2ZW50U291cmNlIjoiYXdzOmR5bmFtb2RiIn0=", "PartitionKey": "D1174FF2F6189C4B8B91C573346158AD" }, { "SequenceNumber": "49630754920297146318042064765136834493078514152056553522", "ApproximateArrivalTimestamp": "2022-06-24T14:36:03.966000+09:00", "Data": "eyJhd3NSZWdpb24iOiJhcC1ub3J0aGVhc3QtMSIsImV2ZW50SUQiOiI0NmQ2Mjc3Ni03ZjU1LTQwNGEtODc2Ni1iNDlhYWI4Y2QxZmMiLCJldmVudE5hbWUiOiJNT0RJRlkiLCJ1c2VySWRlbnRpdHkiOm51bGwsInJlY29yZEZvcm1hdCI6ImFwcGxpY2F0aW9uL2pzb24iLCJ0YWJsZU5hbWUiOiJraW5lc2lzLXRlc3QiLCJkeW5hbW9kYiI6eyJBcHByb3hpbWF0ZUNyZWF0aW9uRGF0ZVRpbWUiOjE2NTYwNDg5NjM1NjYsIktleXMiOnsiaWQiOnsiUyI6ImFhYWFhYWFhYWFhIn0sImRhdGV0aW1lIjp7IlMiOiJhYWFhYWFhYWFhYSJ9fSwiTmV3SW1hZ2UiOnsiaWQiOnsiUyI6ImFhYWFhYWFhYWFhIn0sImRhdGV0aW1lIjp7IlMiOiJhYWFhYWFhYWFhYSJ9LCJjY2MiOnsiUyI6ImdvZ29nb2dvIn19LCJPbGRJbWFnZSI6eyJpZCI6eyJTIjoiYWFhYWFhYWFhYWEifSwiZGF0ZXRpbWUiOnsiUyI6ImFhYWFhYWFhYWFhIn0sImNjYyI6eyJTIjoic2FtcGxlIHRleHQifX0sIlNpemVCeXRlcyI6MTIxfSwiZXZlbnRTb3VyY2UiOiJhd3M6ZHluYW1vZGIifQ==", "PartitionKey": "D1174FF2F6189C4B8B91C573346158AD" } ], "NextShardIterator": "AAAAAAAAAAEbQXenaHcCeosgGJwhLcOtqHDk/l5RQk/qOmihRWM/yJirzXs3pArN6Y8sm+gF97rqlDWAvjNvy+MpuUmm+U+29j4qtyUB117A86ImSQYNIA6bT5fkUyUUIr/nutrVFx+3+PwHZeDEx1aACuJL9znIV37rWwrfocGs8zeDbRBStom5Dk84VBYrAubwM9KPZyCRSJvIuZgJHnerHb9PQKC40+O3TcyoMZZ4EoHpt4mhww==", "MillisBehindLatest": 0 } --- ### API Gateway のアクセス元をリソースポリシー機能を使用してCloudFrontのみに限定する方法 date: 2022-06-13 url: https://zatoima.github.io/aws-api-gateway-cloudfront-restrict-resource-policy/ tags: AWS はじめに 下記の通りx-api-keyを使用したアクセス制限の方法もあるが、今回はAPI Gateway のリソースポリシー機能を使用してCloudFrontを限定する API Gateway で Cloudfront 経由のアクセスのみ許可する - ablog https://yohei-a.hatenablog.jp/entry/20210702/1625203047 前提 API Gateway petstoreのサンプルをそのまま使う [ec2-user@bastin ~]$ curl https://hbdqg3riq2.execute-api.ap-northeast-1.amazonaws.com/prod/pets [ { "id": 1, "type": "dog", "price": 249.99 }, { "id": 2, "type": "cat", "price": 124.99 }, { "id": 3, "type": "fish", "price": 0.99 } ] API GatewayをオリジンとしたCloudFrontのディストリビューションを作成 CloudFront経由のアクセスもできるようになった [ec2-user@bastin ~]$ curl https://d3bkz0zeq00fjv.cloudfront.net/prod/pets [ { "id": 1, "type": "dog", "price": 249.99 }, { "id": 2, "type": "cat", "price": 124.99 }, { "id": 3, "type": "fish", "price": 0.99 } ] API Gateway のアクセス元をリソースポリシー機能を使用してCloudFront のみに限定する方法 ここからが本題 CloudFront側でカスタムヘッダーを追加する カスタムヘッダーは第三者にバレない値を設定する必要がある。バレたらアクセスできるので。 API Gateway 側でリソースポリシーを設定 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": "*", "Action": "execute-api:Invoke", "Resource": "arn:aws:execute-api:<リージョン>:<アカウントID>:<API ID>/*/*/*" }, { "Effect": "Deny", "Principal": "*", "Action": "execute-api:Invoke", "Resource": "arn:aws:execute-api:<リージョン>:<アカウントID>:<API ID>/*/*/*", "Condition": { "StringNotEquals": { "aws:Referer": "<第三者から推測されにくい任意の文字列>" } } } ] } ※忘れずにAPIの再デプロイを実施する 上記設定を行うことでCloudFront経由はアクセスが出来、API GatewayのURLからはアクセスが出来ないことを確認出来た。 [ec2-user@bastin ~]$ curl https://d3bkz0zeq00fjv.cloudfront.net/prod/pets [ { "id": 1, "type": "dog", "price": 249.99 }, { "id": 2, "type": "cat", "price": 124.99 }, { "id": 3, "type": "fish", "price": 0.99 } ][ec2-user@bastin ~]$ [ec2-user@bastin ~]$ curl https://hbdqg3riq2.execute-api.ap-northeast-1.amazonaws.com/prod/pets {"Message":"User: anonymous is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:ap-northeast-1:********6200:hbdqg3riq2/prod/GET/pets with an explicit deny"} 参考 オリジンリクエストへのカスタムヘッダーの追加 - Amazon CloudFront --- ### SAMを使用したLambdaのデプロイをCodePipelineに組み込む date: 2022-06-11 url: https://zatoima.github.io/aws-lambda-sam-codepipeline-deploy/ tags: AWS 前提条件 SAM CLIがインストールされていること CodeCommit用のユーザが事前作成されていること AWSCodeCommitPowerUserを付与する AWS CodeCommit の HTTPS Git 認証情報を控えておく。(IAMの認証情報から生成) SAM用のディレクトリ/デプロイ用のファイル準備 [ec2-user@bastin test-sam]$ tree . ├── function │ ├── function.py │ └── requirements.txt ├── samconfig.toml └── template.yaml 1 directory, 4 files [ec2-user@bastin test-sam]$ cat function/function.py import json import requests def lambda_handler(event, context): print(requests.get('https://google.com')) return { 'statusCode': 200, 'body': json.dumps('Hello from Lambda!') } [ec2-user@bastin test-sam]$ [ec2-user@bastin test-sam]$ cat function/requirements.txt requests [ec2-user@bastin test-sam]$ [ec2-user@bastin test-sam]$ cat samconfig.toml version = 0.1 [default] [default.deploy] [default.deploy.parameters] stack_name = "test-sam-app" s3_bucket = "zatoima" s3_prefix = "test-sam-app" region = "ap-northeast-1" capabilities = "CAPABILITY_IAM" [ec2-user@bastin test-sam]$ [ec2-user@bastin test-sam]$ cat template.yaml AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: SAM Template for test-sam-app Globals: Function: Timeout: 3 Resources: Function: Type: AWS::Serverless::Function Properties: FunctionName: test-sam-app CodeUri: function/ Handler: function.lambda_handler Runtime: python3.8 Outputs: Function: Description: "test-sam-app Lambda Function ARN" Value: !GetAtt Function.Arn FunctionIamRole: Description: "Implicit IAM Role created for test-sam-app function" Value: !GetAtt FunctionRole.Arn buildspec.yamlの準備 sam packageでパッケージングするBuildspec.yamlを準備 version: 0.2 phases: install: runtime-versions: python: 3.8 build: commands: - sam package --template-file template.yaml --s3-bucket zatoima --output-template-file packaged-template.yml artifacts: files: - packaged-template.yml CodeCommitの設定 リポジトリをクローンする git clone https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/sam-codecommit [ec2-user@bastin ~]$ git clone https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/sam-codecommit Cloning into 'sam-codecommit'... Username for 'https://git-codecommit.ap-northeast-1.amazonaws.com': codecommituser-at-xxxxxxxxxxxxx Password for 'https://codecommituser-at-xxxxxxxxxxxxx@git-codecommit.ap-northeast-1.amazonaws.com': remote: Counting objects: 3, done. Unpacking objects: 100% (3/3), 349 bytes | 349.00 KiB/s, done. [ec2-user@bastin ~]$ SAMのデプロイ用のファイルをリポジトリにPushする。 [ec2-user@bastin sam-codecommit]$ git push Username for 'https://git-codecommit.ap-northeast-1.amazonaws.com': codecommituser-at-xxxxxxxxxxxxx Password for 'https://codecommituser-at-xxxxxxxxxxxxx@git-codecommit.ap-northeast-1.amazonaws.com': Enumerating objects: 8, done. Counting objects: 100% (8/8), done. Delta compression using up to 2 threads Compressing objects: 100% (6/6), done. Writing objects: 100% (7/7), 1.05 KiB | 1.05 MiB/s, done. Total 7 (delta 0), reused 0 (delta 0), pack-reused 0 To https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/sam-codecommit aed7fe9..70c2d27 main -> main [ec2-user@bastin sam-codecommit]$ こんな感じの状態になる。 CodeBuild 成功後にpackaged-template.ymlがS3に生成 CodePipelineの設定 CodeCommit->CodeBuild->CloudFormation アクションモードにいくつか種類があるので適切なものを選ぶ パイプラインの実行 コードを1行だけ追加。print("test") [ec2-user@bastin function]$ cat function.py import json import requests def lambda_handler(event, context): print("test") print(requests.get('https://google.com')) return { 'statusCode': 200, 'body': json.dumps('Hello from Lambda!') } codecommitへpush cd /home/ec2-user/sam-codecommit git add . git commit -m "Update commit" git push CloudFormation Lambda 参考 CodePipelineを使ってSAMでシンプルなAPI Gatewayをデプロイしてみた | DevelopersIO CodePipelineを step by step でやってみた | DevelopersIO --- ### API Gateway+LambdaのSAMでCanaryデプロイを実施 date: 2022-05-31 url: https://zatoima.github.io/aws-lambda-sam-api-canary-deploy/ tags: AWS 前提条件 SAM CLIがインストールされていること SAM INIT [ec2-user@bastin test]$ sam init You can preselect a particular runtime or package type when using the `sam init` experience. Call `sam init --help` to learn more. Which template source would you like to use? 1 - AWS Quick Start Templates 2 - Custom Template Location Choice: 1 Choose an AWS Quick Start application template 1 - Hello World Example 2 - Multi-step workflow 3 - Serverless API 4 - Scheduled task 5 - Standalone function 6 - Data processing 7 - Infrastructure event management 8 - Machine Learning Template: 1 Use the most popular runtime and package type? (Python and zip) [y/N]: y Would you like to enable X-Ray tracing on the function(s) in your application? [y/N]: y X-Ray will incur an additional cost. View https://aws.amazon.com/xray/pricing/ for more details Project name [sam-app]: Cloning from https://github.com/aws/aws-sam-cli-app-templates (process may take a moment) ----------------------- Generating application: ----------------------- Name: sam-app Runtime: python3.9 Architectures: x86_64 Dependency Manager: pip Application Template: hello-world Output Directory: . Next steps can be found in the README file at ./sam-app/README.md Commands you can use next ========================= [*] Create pipeline: cd sam-app && sam pipeline init --bootstrap [*] Validate SAM template: sam validate [*] Test Function in the Cloud: sam sync --stack-name {stack-name} --watch 作成されたtemplate.yaml Runtime: python3.8だけ実環境に合わせて修正 [ec2-user@bastin sam-app]$ cat template.yaml AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > sam-app Sample SAM Template for sam-app # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst Globals: Function: Timeout: 3 Tracing: Active Resources: HelloWorldFunction: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: CodeUri: hello_world/ Handler: app.lambda_handler Runtime: python3.8 Architectures: - x86_64 Events: HelloWorld: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: Path: /hello Method: get Outputs: # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function # Find out more about other implicit resources you can reference within SAM # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api HelloWorldApi: Description: "API Gateway endpoint URL for Prod stage for Hello World function" Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/" HelloWorldFunction: Description: "Hello World Lambda Function ARN" Value: !GetAtt HelloWorldFunction.Arn HelloWorldFunctionIamRole: Description: "Implicit IAM Role created for Hello World function" Value: !GetAtt HelloWorldFunctionRole.Arn SAM BUILD [ec2-user@bastin sam-app]$ sam build Your template contains a resource with logical ID "ServerlessRestApi", which is a reserved logical ID in AWS SAM. It could result in unexpected behaviors and is not recommended. Building codeuri: /home/ec2-user/tmp/test/sam-app/hello_world runtime: python3.8 metadata: {} architecture: x86_64 functions: ['HelloWorldFunction'] Running PythonPipBuilder:ResolveDependencies Running PythonPipBuilder:CopySource Build Succeeded Built Artifacts : .aws-sam/build Built Template : .aws-sam/build/template.yaml Commands you can use next ========================= [*] Validate SAM template: sam validate [*] Invoke Function: sam local invoke [*] Test Function in the Cloud: sam sync --stack-name {stack-name} --watch [*] Deploy: sam deploy --guided [ec2-user@bastin sam-app]$ SAM DEPLOY [ec2-user@bastin sam-app]$ sam deploy --guided Configuring SAM deploy ====================== Looking for config file [samconfig.toml] : Not found Setting default arguments for 'sam deploy' ========================================= Stack Name [sam-app]: AWS Region [ap-northeast-1]: #Shows you resources changes to be deployed and require a 'Y' to initiate deploy Confirm changes before deploy [y/N]: n #SAM needs permission to be able to create roles to connect to the resources in your template Allow SAM CLI IAM role creation [Y/n]: y #Preserves the state of previously provisioned resources when an operation fails Disable rollback [y/N]: n HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y Save arguments to configuration file [Y/n]: y SAM configuration file [samconfig.toml]: SAM configuration environment [default]: Looking for resources needed for deployment: Creating the required resources... Successfully created! Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-g2l8ba259m80 A different default S3 bucket can be set in samconfig.toml Saved arguments to config file Running 'sam deploy' for future deployments will use the parameters saved above. The above parameters can be changed by modifying samconfig.toml Learn more about samconfig.toml syntax at https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html Uploading to sam-app/abd834336b3b9a077d1ef4926a7e0945 458806 / 458806 (100.00%) Deploying with following values =============================== Stack name : sam-app Region : ap-northeast-1 Confirm changeset : False Disable rollback : False Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-g2l8ba259m80 Capabilities : ["CAPABILITY_IAM"] Parameter overrides : {} Signing Profiles : {} Initiating deployment ===================== Uploading to sam-app/3c45e542dd42c86b02969d562b823531.template 1199 / 1199 (100.00%) Waiting for changeset to be created.. ~省略~ Successfully created/updated stack - sam-app in ap-northeast-1 試しに実行 [ec2-user@bastin sam-app]$ for i in {1..10}; do curl -w '\n' https://ody2prbd53.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/; done {"message": "hello world"} {"message": "hello world"} {"message": "hello world"} {"message": "hello world"} {"message": "hello world"} {"message": "hello world"} {"message": "hello world"} {"message": "hello world"} {"message": "hello world"} {"message": "hello world"} [ec2-user@bastin sam-app]$ Pythonコードを一部修正。"message": "hello world v2",に。 [ec2-user@bastin sam-app]$ cat hello_world/app.py import json # import requests def lambda_handler(event, context): """Sample pure Lambda function Parameters ---------- event: dict, required API Gateway Lambda Proxy Input Format Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format context: object, required Lambda Context runtime methods and attributes Context doc: https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html Returns ------ API Gateway Lambda Proxy Output Format: dict Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html """ # try: # ip = requests.get("http://checkip.amazonaws.com/") # except requests.RequestException as e: # # Send some context about this error to Lambda Logs # print(e) # raise e return { "statusCode": 200, "body": json.dumps({ "message": "hello world v2", # "location": ip.text.replace("\n", "") }), } SAMテンプレートを修正 下記を追加 AutoPublishAlias: live DeploymentPreference: Type: Linear10PercentEvery10Minutes [ec2-user@bastin sam-app]$ cat template.yaml AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > sam-app Sample SAM Template for sam-app # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst Globals: Function: Timeout: 3 Tracing: Active Resources: HelloWorldFunction: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: CodeUri: hello_world/ Handler: app.lambda_handler Runtime: python3.8 Architectures: - x86_64 AutoPublishAlias: live DeploymentPreference: Type: Linear10PercentEvery10Minutes Events: HelloWorld: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: Path: /hello Method: get sam build&Deploy [ec2-user@bastin sam-app]$ sam build Your template contains a resource with logical ID "ServerlessRestApi", which is a reserved logical ID in AWS SAM. It could result in unexpected behaviors and is not recommended. Building codeuri: /home/ec2-user/tmp/test/sam-app/hello_world runtime: python3.8 metadata: {} architecture: x86_64 functions: ['HelloWorldFunction'] Running PythonPipBuilder:ResolveDependencies Running PythonPipBuilder:CopySource Build Succeeded Built Artifacts : .aws-sam/build Built Template : .aws-sam/build/template.yaml Commands you can use next ========================= [*] Validate SAM template: sam validate [*] Invoke Function: sam local invoke [*] Test Function in the Cloud: sam sync --stack-name {stack-name} --watch [*] Deploy: sam deploy --guided [ec2-user@bastin sam-app]$ sam deploy Uploading to sam-app/81d9b12cbf5541a6c9ff2fcf17671808 458809 / 458809 (100.00%) Deploying with following values =============================== Stack name : sam-app Region : ap-northeast-1 Confirm changeset : False Disable rollback : False Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-g2l8ba259m80 Capabilities : ["CAPABILITY_IAM"] Parameter overrides : {} Signing Profiles : {} Initiating deployment ===================== Uploading to sam-app/5e5bb4c759ce5a0dac0216a727528b16.template 1300 / 1300 (100.00%) Waiting for changeset to be created.. ~省略~ Successfully created/updated stack - sam-app in ap-northeast-1 DeploymentPreference直後はエイリアス管理されていないので2回ほどコードを修正して動作を確認する。 [ec2-user@bastin ~]$ for i in {1..20}; do curl -w '\n' https://ody2prbd53.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/; done {"message": "hello world v2"} {"message": "hello world v2"} {"message": "hello world v2"} {"message": "hello world v2"} {"message": "hello world v2"} {"message": "hello world v2"} {"message": "hello world v2"} {"message": "hello world v2"} {"message": "hello world v2"} {"message": "hello world v2"} {"message": "hello world v3"} {"message": "hello world v2"} {"message": "hello world v2"} {"message": "hello world v2"} {"message": "hello world v2"} {"message": "hello world v2"} {"message": "hello world v2"} {"message": "hello world v2"} {"message": "hello world v2"} {"message": "hello world v2"} [ec2-user@bastin ~]$ --- ### S3へのファイルのPUTを検知してLamdbaからAurora PostgreSQLのテーブルへCSV形式のデータをロード date: 2022-05-25 url: https://zatoima.github.io/aws-aurora-postgres-lambda-s3-event/ tags: AWS ※RDS Proxyやパスワードの外出し等やるべきことやっていません。 S3のイベント構造 Amazon S3 がイベントを発行する場合のJSONはこちら。 イベントメッセージの構造 - Amazon Simple Storage Service https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/notification-content-structure.html { "Records":[ { "eventVersion":"2.2", "eventSource":"aws:s3", "awsRegion":"us-west-2", "eventTime":"The time, in ISO-8601 format, for example, 1970-01-01T00:00:00.000Z, when Amazon S3 finished processing the request", "eventName":"event-type", "userIdentity":{ "principalId":"Amazon-customer-ID-of-the-user-who-caused-the-event" }, "requestParameters":{ "sourceIPAddress":"ip-address-where-request-came-from" }, "responseElements":{ "x-amz-request-id":"Amazon S3 generated request ID", "x-amz-id-2":"Amazon S3 host that processed the request" }, "s3":{ "s3SchemaVersion":"1.0", "configurationId":"ID found in the bucket notification configuration", "bucket":{ "name":"bucket-name", "ownerIdentity":{ "principalId":"Amazon-customer-ID-of-the-bucket-owner" }, "arn":"bucket-ARN" }, "object":{ "key":"object-key", "size":"object-size in bytes", "eTag":"object eTag", "versionId":"object version if bucket is versioning-enabled, otherwise null", "sequencer": "a string representation of a hexadecimal value used to determine event sequence, only used with PUTs and DELETEs" } }, "glacierEventData": { "restoreEventData": { "lifecycleRestorationExpiryTime": "The time, in ISO-8601 format, for example, 1970-01-01T00:00:00.000Z, of Restore Expiry", "lifecycleRestoreStorageClass": "Source storage class for restore" } } } ] } Lambda側でトリガーを追加 Lamdba Pythonスクリプト S3へのCSVファイルのPUTを検知してAurora PostgreSQLのテーブルにロードをする簡易スクリプト。特にエラーハンドリング等は実施していないので注意。 import psycopg2 import psycopg2.extras import time import datetime import logging import boto3 import sys import os def lambda_handler(event, context): print('event: {}'.format(event)) print('context: {}'.format(context)) logger = logging.getLogger() logger.setLevel(logging.INFO) s3_client = boto3.client('s3') conn = psycopg2.connect("host=auroraserverlessv2.cluster-xxxxx.ap-northeast-1.rds.amazonaws.com port=5432 dbname=postgres user=postgres password=postgres") for record in event['Records']: bucket = record['s3']['bucket']['name'] key = record['s3']['object']['key'] s3location = 's3://' + bucket + '/' + key logger.info(s3location) logger.info(bucket) logger.info(key) cur = conn.cursor() logger.info("SUCCESS: Connection to RDS Aurora instance succeeded") sql = "SELECT aws_s3.table_import_from_s3('ddb', '', '(format csv)', %s , %s , 'ap-northeast-1');" logger.info(sql) with conn.cursor() as cur: cur.execute(sql, (bucket, key)) conn.commit() logger.info('Data loaded from S3 into Aurora') conn.commit() cur.close() conn.close() 補足 aws_s3.table_import_from_s3を使っているのでAurora側にIAMロールの設定や拡張機能の設定が必要となることに注意。 S3からRDS/Aurora(PostgreSQL)にCSVファイルをインポートする | my opinion is my own 👋 --- ### PostgreSQL のテーブルをリネームした場合、統計情報やインデックス、バッファキャッシュはどうなるか? date: 2022-05-22 url: https://zatoima.github.io/aws-postgresql-rename-table-index-analyze-buffer/ tags: PostgreSQL 結論 バッファキャッシュ、インデックス、統計情報はリネーム先に引き継がれる コマンド -- テーブル準備 create table t1_work(a numeric primary key,b varchar(20)); insert into t1_work values(1,'test'); -- pg_buffercacheの有効化 create extension pg_buffercache; -- 統計情報の確認 analyze t1_work; select * from pg_stat_user_tables where relname='t1_work'; -- インデックス情報の確認 select * from pg_indexes where tablename='t1_work'; -- キャッシュ情報の確認 select c.relname, count(*) as buffers from pg_buffercache as b inner join pg_class as c on b.relfilenode = pg_relation_filenode(c.oid) and b.reldatabase in (0, (select oid from pg_database where datname = current_database())) where c.relname='t1_work' group by c.relname order by 2 desc LIMIT 30; -- テーブル名の変更 ALTER TABLE t1_work RENAME TO t1; -- 統計情報の確認 select * from pg_stat_user_tables where relname='t1'; -- インデックス情報の確認 select * from pg_indexes where tablename='t1'; -- キャッシュ確認 select c.relname, count(*) as buffers from pg_buffercache as b inner join pg_class as c on b.relfilenode = pg_relation_filenode(c.oid) and b.reldatabase in (0, (select oid from pg_database where datname = current_database())) where c.relname='t1' group by c.relname order by 2 desc LIMIT 30; -- テーブル削除 drop table t1; drop table t1_work; バッファキャッシュ リネーム前 postgres=> select c.relname, count(*) as buffers postgres-> from pg_buffercache as b postgres-> inner join pg_class as c on b.relfilenode = pg_relation_filenode(c.oid) and b.reldatabase in (0, (select oid from pg_database where datname = current_database())) postgres-> where c.relname='t1_work' postgres-> group by c.relname postgres-> order by 2 desc postgres-> LIMIT 30; relname | buffers ---------+--------- t1_work | 1 (1 row) リネーム後 postgres=> select c.relname, count(*) as buffers postgres-> from pg_buffercache as b postgres-> inner join pg_class as c on b.relfilenode = pg_relation_filenode(c.oid) and b.reldatabase in (0, (select oid from pg_database where datname = current_database())) postgres-> where c.relname='t1' postgres-> group by c.relname postgres-> order by 2 desc postgres-> LIMIT 30; relname | buffers ---------+--------- t1 | 1 (1 row) 統計情報 リネーム前 postgres=> select * from pg_stat_user_tables where relname='t1_work'; relid | schemaname | relname | seq_scan | seq_tup_read | idx_scan | idx_tup_fetch | n_tup_ins | n_tup_upd | n_tup_del | n_tup_hot_upd | n_live_tup | n_dead_tup | n_mod_since_analyze | n_ins_since_vacuum | last_vacuum | last_autovacuum | last_analyze | last_autoanalyze | vacuum_count | autovacuum_c ount | analyze_count | autoanalyze_count -------+------------+---------+----------+--------------+----------+---------------+-----------+-----------+-----------+---------------+------------+------------+---------------------+--------------------+-------------+-----------------+-------------------------------+------------------+--------------+------------- -----+---------------+------------------- 24688 | public | t1_work | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | | | 2022-05-18 04:21:08.540609+00 | | 0 | 0 | 1 | 0 (1 row) リネーム後 postgres=> select * from pg_stat_user_tables where relname='t1'; relid | schemaname | relname | seq_scan | seq_tup_read | idx_scan | idx_tup_fetch | n_tup_ins | n_tup_upd | n_tup_del | n_tup_hot_upd | n_live_tup | n_dead_tup | n_mod_since_analyze | n_ins_since_vacuum | last_vacuum | last_autovacuum | last_analyze | last_autoanalyze | vacuum_count | autovacuum_c ount | analyze_count | autoanalyze_count -------+------------+---------+----------+--------------+----------+---------------+-----------+-----------+-----------+---------------+------------+------------+---------------------+--------------------+-------------+-----------------+-------------------------------+------------------+--------------+------------- -----+---------------+------------------- 24688 | public | t1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | | | 2022-05-18 04:21:08.540609+00 | | 0 | 0 | 1 | 0 (1 row) インデックス リネーム前 postgres=> select * from pg_indexes where tablename='t1_work'; schemaname | tablename | indexname | tablespace | indexdef ------------+-----------+--------------+------------+-------------------------------------------------------------------- public | t1_work | t1_work_pkey | | CREATE UNIQUE INDEX t1_work_pkey ON public.t1_work USING btree (a) (1 row) リネーム後 postgres=> select * from pg_indexes where tablename='t1'; schemaname | tablename | indexname | tablespace | indexdef ------------+-----------+--------------+------------+--------------------------------------------------------------- public | t1 | t1_work_pkey | | CREATE UNIQUE INDEX t1_work_pkey ON public.t1 USING btree (a) (1 row) 実行ログ postgres=> create table t1_work(a numeric primary key,b varchar(20)); CREATE TABLE postgres=> insert into t1_work values(1,'test'); INSERT 0 1 postgres=> create extension pg_buffercache; ERROR: extension "pg_buffercache" already exists postgres=> \dx List of installed extensions Name | Version | Schema | Description ----------------+---------+------------+--------------------------------------------- aws_commons | 1.2 | public | Common data types across AWS services aws_s3 | 1.1 | public | AWS S3 extension for importing data from S3 pg_buffercache | 1.3 | public | examine the shared buffer cache plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language (4 rows) postgres=> analyze t1_work; ANALYZE postgres=> select * from pg_stat_user_tables where relname='t1_work'; relid | schemaname | relname | seq_scan | seq_tup_read | idx_scan | idx_tup_fetch | n_tup_ins | n_tup_upd | n_tup_del | n_tup_hot_upd | n_live_tup | n_dead_tup | n_mod_since_analyze | n_ins_since_vacuum | last_vacuum | last_autovacuum | last_analyze | last_autoanalyze | vacuum_count | autovacuum_c ount | analyze_count | autoanalyze_count -------+------------+---------+----------+--------------+----------+---------------+-----------+-----------+-----------+---------------+------------+------------+---------------------+--------------------+-------------+-----------------+-------------------------------+------------------+--------------+------------- -----+---------------+------------------- 24688 | public | t1_work | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | | | 2022-05-18 04:21:08.540609+00 | | 0 | 0 | 1 | 0 (1 row) postgres=> select * from pg_indexes where tablename='t1_work'; schemaname | tablename | indexname | tablespace | indexdef ------------+-----------+--------------+------------+-------------------------------------------------------------------- public | t1_work | t1_work_pkey | | CREATE UNIQUE INDEX t1_work_pkey ON public.t1_work USING btree (a) (1 row) postgres=> select c.relname, count(*) as buffers postgres-> from pg_buffercache as b postgres-> inner join pg_class as c on b.relfilenode = pg_relation_filenode(c.oid) and b.reldatabase in (0, (select oid from pg_database where datname = current_database())) postgres-> where c.relname='t1_work' postgres-> group by c.relname postgres-> order by 2 desc postgres-> LIMIT 30; relname | buffers ---------+--------- t1_work | 1 (1 row) postgres=> ALTER TABLE t1_work RENAME TO t1; ALTER TABLE postgres=> select * from pg_stat_user_tables where relname='t1'; relid | schemaname | relname | seq_scan | seq_tup_read | idx_scan | idx_tup_fetch | n_tup_ins | n_tup_upd | n_tup_del | n_tup_hot_upd | n_live_tup | n_dead_tup | n_mod_since_analyze | n_ins_since_vacuum | last_vacuum | last_autovacuum | last_analyze | last_autoanalyze | vacuum_count | autovacuum_c ount | analyze_count | autoanalyze_count -------+------------+---------+----------+--------------+----------+---------------+-----------+-----------+-----------+---------------+------------+------------+---------------------+--------------------+-------------+-----------------+-------------------------------+------------------+--------------+------------- -----+---------------+------------------- 24688 | public | t1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | | | 2022-05-18 04:21:08.540609+00 | | 0 | 0 | 1 | 0 (1 row) postgres=> select * from pg_indexes where tablename='t1'; schemaname | tablename | indexname | tablespace | indexdef ------------+-----------+--------------+------------+--------------------------------------------------------------- public | t1 | t1_work_pkey | | CREATE UNIQUE INDEX t1_work_pkey ON public.t1 USING btree (a) (1 row) postgres=> select c.relname, count(*) as buffers postgres-> from pg_buffercache as b postgres-> inner join pg_class as c on b.relfilenode = pg_relation_filenode(c.oid) and b.reldatabase in (0, (select oid from pg_database where datname = current_database())) postgres-> where c.relname='t1' postgres-> group by c.relname postgres-> order by 2 desc postgres-> LIMIT 30; relname | buffers ---------+--------- t1 | 1 (1 row) postgres=> postgres=> postgres=> select c.relname, count(*) as buffers postgres-> from pg_buffercache as b postgres-> inner join pg_class as c on b.relfilenode = pg_relation_filenode(c.oid) and b.reldatabase in (0, (select oid from pg_database where datname = current_database())) postgres-> where c.relname like 't1%' postgres-> group by c.relname postgres-> order by 2 desc postgres-> LIMIT 30; relname | buffers --------------+--------- t1_work_pkey | 2 t1 | 1 (2 rows) postgres=> postgres=> drop table t1; DROP TABLE postgres=> drop table t1_work; ERROR: table "t1_work" does not exist postgres=> --- ### AWS SAM CLI を使用したLambdaのデプロイ date: 2022-05-21 url: https://zatoima.github.io/aws-lambda-sam-deploy/ tags: AWS SAM CLIのインストール コマンド wget https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip unzip aws-sam-cli-linux-x86_64.zip -d sam-installation sudo ./sam-installation/install sam --version 事前準備 Python3.8系がインストールされていないとエラーになったのでインストール [ec2-user@bastin test-sam]$ sam build Building codeuri: /home/ec2-user/test-sam/function runtime: python3.8 metadata: {} architecture: x86_64 functions: [‘Function’] Build Failed Error: PythonPipBuilder:Validation - Binary validation failed for python, searched for python in following locations : [’/usr/bin/python’] which did not satisfy constraints for runtime: python3.8. Do you have python for runtime: python3.8 on your PATH? sudo amazon-linux-extras install python3.8 ディレクトリ/デプロイ用のファイル準備 [ec2-user@bastin test-sam]$ tree . ├── function │ ├── function.py │ └── requirements.txt ├── samconfig.toml └── template.yaml 1 directory, 4 files [ec2-user@bastin test-sam]$ cat function/function.py import json import requests def lambda_handler(event, context): print(requests.get('https://google.com')) return { 'statusCode': 200, 'body': json.dumps('Hello from Lambda!') } [ec2-user@bastin test-sam]$ [ec2-user@bastin test-sam]$ cat function/requirements.txt requests [ec2-user@bastin test-sam]$ [ec2-user@bastin test-sam]$ cat samconfig.toml version = 0.1 [default] [default.deploy] [default.deploy.parameters] stack_name = "test-sam-app" s3_bucket = "zatoima" s3_prefix = "test-sam-app" region = "ap-northeast-1" capabilities = "CAPABILITY_IAM" [ec2-user@bastin test-sam]$ [ec2-user@bastin test-sam]$ cat template.yaml AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: SAM Template for test-sam-app Globals: Function: Timeout: 3 Resources: Function: Type: AWS::Serverless::Function Properties: FunctionName: test-sam-app CodeUri: function/ Handler: function.lambda_handler Runtime: python3.8 Outputs: Function: Description: "test-sam-app Lambda Function ARN" Value: !GetAtt Function.Arn FunctionIamRole: Description: "Implicit IAM Role created for test-sam-app function" Value: !GetAtt FunctionRole.Arn ビルド、デプロイ [ec2-user@bastin test-sam]$ sam build Building codeuri: /home/ec2-user/test-sam/function runtime: python3.8 metadata: {} architecture: x86_64 functions: ['Function'] Running PythonPipBuilder:ResolveDependencies Running PythonPipBuilder:CopySource Build Succeeded Built Artifacts : .aws-sam/build Built Template : .aws-sam/build/template.yaml Commands you can use next ========================= [*] Validate SAM template: sam validate [*] Invoke Function: sam local invoke [*] Test Function in the Cloud: sam sync --stack-name {stack-name} --watch [*] Deploy: sam deploy --guided [ec2-user@bastin test-sam]$ [ec2-user@bastin test-sam]$ [ec2-user@bastin test-sam]$ sam deploy Uploading to test-sam-app/70531b5489f5a99ab4c62e4acc57d0ef 452386 / 452386 (100.00%) Deploying with following values =============================== Stack name : test-sam-app Region : ap-northeast-1 Confirm changeset : False Disable rollback : False Deployment s3 bucket : zatoima Capabilities : ["CAPABILITY_IAM"] Parameter overrides : {} Signing Profiles : {} Initiating deployment ===================== Uploading to test-sam-app/ba13ca287976cbfe7f0c7cda0b66556e.template 725 / 725 (100.00%) Waiting for changeset to be created.. ~省略~ Successfully created/updated stack - test-sam-app in ap-northeast-1 CloudFormation Lambda --- ### Lambdaからawslambda-psycopg2を使用してAurora PostgreSQLに接続 date: 2022-05-17 url: https://zatoima.github.io/aws-aurora-postgres-psycopg2-lambda/ tags: AWS Lambda上で psycopg2 をそのまま利用するにはひと手間必要なのでawslambda-psycopg2を使ってAurora PostgreSQLに接続する。 ライブラリをダウンロード git clone https://github.com/jkehler/awslambda-psycopg2.git [ec2-user@bastin lambda]$ git clone https://github.com/jkehler/awslambda-psycopg2.git Cloning into 'awslambda-psycopg2'... remote: Enumerating objects: 210, done. remote: Counting objects: 100% (26/26), done. remote: Compressing objects: 100% (21/21), done. remote: Total 210 (delta 5), reused 22 (delta 5), pack-reused 184 Receiving objects: 100% (210/210), 3.57 MiB | 8.89 MiB/s, done. Resolving deltas: 100% (81/81), done. [ec2-user@bastin lambda]$ ls -l total 0 drwxrwxr-x 8 ec2-user ec2-user 153 May 6 15:41 awslambda-psycopg2 デプロイ用のパッケージの作成 mkdir -p upload-lambda/package touch upload-lambda/lambda_function.py mv awslambda-psycopg2/psycopg2-3.8 upload-lambda/package/psycopg2 テスト用のスクリプトを準備 動作させるだけのスクリプトをとりあえず準備。 cat << EOF > upload-lambda/lambda_function.py import psycopg2 def lambda_handler(event, context): return 'ok' EOF psycopg2-binaryをzipファイルに含める cd ./upload-lambda/package/ zip -r ../my-deployment-package.zip . lambda_function.pyをzipファイルに含める cd .. zip -r ./my-deployment-package.zip lambda_function.py 下記の通りのフォルダ構成となっていることを確認 tree upload-lambda upload-lambda ├── lambda_function.py ├── my-deployment-package.zip └── package └── psycopg2 Lambda側のVPCの設定 VPCを使用する設定にして、Aurora側に接続できるようなセキュリティグループ設定を行う。 簡易確認 ここまでやってDeploy→Testで正常に動作することを確認する。 接続用スクリプトの準備 import psycopg2 import psycopg2.extras import time import datetime import logging import sys import os def lambda_handler(event, context): print('event: {}'.format(event)) print('context: {}'.format(context)) logger = logging.getLogger() logger.setLevel(logging.INFO) conn = psycopg2.connect("host=auroraserverlessv2.cluster-xxxxxx.ap-northeast-1.rds.amazonaws.com port=5432 dbname=postgres user=postgres password=postgres") cur = conn.cursor() logger.info("SUCCESS: Connection to RDS Aurora instance succeeded") sql = "test用のSQL" logger.info(sql) with conn.cursor() as cur: cur.execute(sql, (bucket, key)) conn.commit() conn.commit() cur.close() conn.close() デプロイして正常にいくかどうかを確認する --- ### pgAdmin4からAurora PostgreSQLへ踏み台サーバのポートフォワード経由で接続する date: 2022-05-09 url: https://zatoima.github.io/aws-aurora-postgres-pgadmin4-bastin-connect/ tags: AWS, Aurora SSHクライアント側の設定 XShellというSSHクライアント使っていますが、Teratermでも同じような設定が可能。 pgAdmin4の設定 Generalで任意の名前を追加 SSHクライアントで指定したlocalhostとポート番号を指定する 正常ログイン後のダッシュボード --- ### DynamoDBからkinesis firehose経由でS3に出力時にJSON形式からCSV形式に変換するLamdba用のPythonスクリプト date: 2022-05-06 url: https://zatoima.github.io/aws-dynamodb-to-s3-csv-transform-python-lamdba/ tags: AWS はじめに DynamoDBへの更新をS3に連携したい場合は下記の通りkinesis firehoseを経由させることで簡単にできるようになった。(従来はDynamoDB-Lamdba-Kinesisとすることが必要だった。) DynamoDBからkinesis firehose経由でS3に出力 | my opinion is my own 👋 https://zatoima.github.io/aws-dynamodb-to-s3-by-kinesis/ が、不要なレコードも一緒に出力されるので必要なものだけを抽出したい場合は、Kinesis firehoseの変換機能を使用する必要がある。Node.jsのスクリプトは公式からの提供されているが、Pythonはあまり見つけられなかった。 {"awsRegion":"ap-northeast-1","eventID":"1e84f1ca-438d-4837-a6bd-aa4592be6f8a","eventName":"MODIFY","userIdentity":null,"recordFormat":"application/json","tableName":"cities","dynamodb":{"ApproximateCreationDateTime":1651495525900,"Keys":{"key":{"S":"t0926"}},"NewImage":{"population":{"N":"54148"},"key":{"S":"t0926"},"name":{"S":"下野"},"date_mod":{"S":"1950-9-7"}},"OldImage":{"population":{"N":"56148"},"key":{"S":"t0926"},"name":{"S":"下野"},"date_mod":{"S":"1950-9-7"}},"SizeBytes":104},"eventSource":"aws:dynamodb"} 必要な設定 Firehose側でS3に保存時に変換したい場合は、Transform source records with AWS Lambdaをenableに設定してLambda Functionを設定する DynamoDB側のテーブル構造 idとdatetimeだけが用意されているテーブル 下記スクリプトで適当にデータを挿入する。 for i in {0..10000} do NOW=`date --iso-8601=seconds` aws dynamodb put-item --table-name dynamotest --item "{ \"datetime\": { \"S\": \"${NOW}\" }, \"id\": { \"S\": \"${i}\" } }" echo $i sleep $(($RANDOM % 5)) done LambdaのPythonスクリプト Kinesis Firehose側の決まりごとに沿う必要があることに注意。 Amazon Kinesis Data Firehose のデータ変換 - Amazon Kinesis Data Firehose https://docs.aws.amazon.com/ja_jp/firehose/latest/dev/data-transformation.html DynamoDB StreamsとKinesis Data Firehoseを使ったサーバーレスリアルタイムETL - Qiita https://qiita.com/kzk-maeda/items/6dd02b9b567a6dd063fd Kinesis Data Firehoseから連携されたPayload Sizeが6MBを超えるときは、PayloadをFirehoseに戻す必要がある さらに、その戻すRecord数が500を超える場合は分割する必要がある Transform処理が完了したデータをFirehoseに戻す際、所定フォーマットにしたがった形式で、Dataの実態はbase64でencordする必要がある 下記のスクリプトはペイロード制限やRecord数は考慮していないので注意。更新量が多いDynamoDBに関しては要注意かもしれない。 import json import base64 def lambda_handler(event, context): results = [] records = event["records"] for record in records: record_id = record.get('recordId') data = json.loads(base64.b64decode(record.get('data'))) #print("Raw Data : " + str(data)) id = data['dynamodb']['Keys']['id']['S'] datetime = data['dynamodb']['Keys']['datetime']['S'] #print("New Data : " + str(id) + str(datetime)) return_data = ','.join([id,datetime]) + '\n' #print("return_data : " + str(return_data)) data = base64.b64encode(return_data.encode()) results.append({ "result":"Ok", "recordId":record_id, "data":data }) return { "records":results } なお、DynamoDB側から流れてくるJSONデータは下記なので、こちらのJSONデータをパースして必要なものだけを抽出する。今回はカラム(idとdatetime)に対する挿入操作をCSVで出力するようにした。 ※サンプルなので、実際のカラムではないです { "Records": [ { "eventID": "c4ca4238a0b923820dcc509a6f75849b", "eventName": "INSERT", "eventVersion": "1.1", "eventSource": "aws:dynamodb", "awsRegion": "us-east-1", "dynamodb": { "Keys": { "Id": { "N": "101" } }, "NewImage": { "Message": { "S": "New item!" }, "Id": { "N": "101" } }, "ApproximateCreationDateTime": 1428537600, "SequenceNumber": "4421584500000000017450439091", "SizeBytes": 26, "StreamViewType": "NEW_AND_OLD_IMAGES" }, "eventSourceARN": "arn:aws:dynamodb:us-east-1:123456789012:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899" }, { "eventID": "c81e728d9d4c2f636f067f89cc14862c", "eventName": "MODIFY", "eventVersion": "1.1", "eventSource": "aws:dynamodb", "awsRegion": "us-east-1", "dynamodb": { "Keys": { "Id": { "N": "101" } }, "NewImage": { "Message": { "S": "This item has changed" }, "Id": { "N": "101" } }, "OldImage": { "Message": { "S": "New item!" }, "Id": { "N": "101" } }, "ApproximateCreationDateTime": 1428537600, "SequenceNumber": "4421584500000000017450439092", "SizeBytes": 59, "StreamViewType": "NEW_AND_OLD_IMAGES" }, "eventSourceARN": "arn:aws:dynamodb:us-east-1:123456789012:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899" }, { "eventID": "eccbc87e4b5ce2fe28308fd9f2a7baf3", "eventName": "REMOVE", "eventVersion": "1.1", "eventSource": "aws:dynamodb", "awsRegion": "us-east-1", "dynamodb": { "Keys": { "Id": { "N": "101" } }, "OldImage": { "Message": { "S": "This item has changed" }, "Id": { "N": "101" } }, "ApproximateCreationDateTime": 1428537600, "SequenceNumber": "4421584500000000017450439093", "SizeBytes": 38, "StreamViewType": "NEW_AND_OLD_IMAGES" }, "eventSourceARN": "arn:aws:dynamodb:us-east-1:123456789012:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899" } ] } 後日追記①: Node.jsであれば下記を参考 'use strict'; console.log('Loading function'); /* Stock Ticker format parser */ const parser = /^\{\"TICKER_SYMBOL\"\:\"[A-Z]+\"\,\"SECTOR\"\:"[A-Z]+\"\,\"CHANGE\"\:[-.0-9]+\,\"PRICE\"\:[-.0-9]+\}/; exports.handler = (event, context, callback) => { let success = 0; // Number of valid entries found let failure = 0; // Number of invalid entries found let dropped = 0; // Number of dropped entries /* Process the list of records and transform them */ const output = event.records.map((record) => { const entry = (new Buffer(record.data, 'base64')).toString('utf8'); let match = parser.exec(entry); if (match) { let parsed_match = JSON.parse(match); var milliseconds = new Date().getTime(); /* Add timestamp and convert to CSV */ const result = `${milliseconds},${parsed_match.TICKER_SYMBOL},${parsed_match.SECTOR},${parsed_match.CHANGE},${parsed_match.PRICE}`+"\n"; const payload = (new Buffer(result, 'utf8')).toString('base64'); if (parsed_match.SECTOR != 'RETAIL') { /* Dropped event, notify and leave the record intact */ dropped++; return { recordId: record.recordId, result: 'Dropped', data: record.data, }; } else { /* Transformed event */ success++; return { recordId: record.recordId, result: 'Ok', data: payload, }; } } else { /* Failed event, notify the error and leave the record intact */ console.log("Failed event : "+ record.data); failure++; return { recordId: record.recordId, result: 'ProcessingFailed', data: record.data, }; } /* This transformation is the "identity" transformation, the data is left intact return { recordId: record.recordId, result: 'Ok', data: record.data, } */ }); console.log(`Processing completed. Successful records ${output.length}.`); callback(null, { records: output }); }; 後日追記②: 下記を全面的に採用させていただき、そのままではエラーで動作しなかったため、一部修正して動作するようにした。 DynamoDB StreamsとKinesis Data Firehoseを使ったサーバーレスリアルタイムETL - Qiita https://qiita.com/kzk-maeda/items/6dd02b9b567a6dd063fd import json import boto3 import base64 from datetime import datetime PAYLOAD_MAX_SIZE = 6000000 MAX_RECORD_COUNT = 500 def transform(data): """ データ変換関数 """ data['NewColumn'] = 'New Value' # Change Schema id = data['dynamodb']['Keys']['id']['S'] datetime = data['dynamodb']['Keys']['datetime']['S'] print("New Data : " + str(id) + str(datetime)) return_data = ','.join([id,datetime]) print("return_data : " + str(return_data)) return return_data def proceed_records(records): """ transform each data and yield each record """ for record in records: record_id = record.get('recordId') data = json.loads(base64.b64decode(record.get('data'))) print("Raw Data : " + str(data)) try: transformed_data = transform(data) result = 'Ok' except Exception as e: print(e) transformed_data = data result = 'ProcessingFailed' print("New Data : " + str(transformed_data)) proceeded_data = json.dumps(transformed_data) + '\n' proceeded_data = str(transformed_data) + '\n' return_record = { "recordId": record_id, "result": result, "data": base64.b64encode(proceeded_data.encode('utf-8')) } yield return_record def put_records_to_firehose(streamName, records, client): print('Trying to return record to firehose') print(f'Item count: {len(records)}') print(f'Record: {str(records)}') try: response = client.put_record_batch(DeliveryStreamName=streamName, Records=records) except Exception as e: # failedRecords = records errMsg = str(e) print(errMsg) def lambda_handler(event, context): invocation_id = event.get('invocationId') event_records = event.get('records') # Transform Data records = list(proceed_records(event_records)) # Check Data projected_size = 0 # Responseサイズが6MBを超えない様制御 data_by_record_id = {rec['recordId']: _create_reingestion_record(rec) for rec in event['records']} total_records_to_be_reingested = 0 records_to_reingest = [] put_record_batches = [] for idx, rec in enumerate(records): if rec['result'] != 'Ok': continue projected_size += len(rec['data']) + len(rec['recordId']) if projected_size > PAYLOAD_MAX_SIZE: """ Lambda 同期呼び出しモードには、リクエストとレスポンスの両方について、 ペイロードサイズに 6 MB の制限があります。 https://docs.aws.amazon.com/ja_jp/firehose/latest/dev/data-transformation.html """ print(f"Payload size has been exceeded over {PAYLOAD_MAX_SIZE/1000/1000}MB") total_records_to_be_reingested += 1 records_to_reingest.append( _get_reingestion_record(data_by_record_id[rec['recordId']]) ) records[idx]['result'] = 'Dropped' del(records[idx]['data']) if len(records_to_reingest) == MAX_RECORD_COUNT: """ Each PutRecordBatch request supports up to 500 records. https://docs.aws.amazon.com/firehose/latest/APIReference/API_PutRecordBatch.html """ print(f'Records count has been exceeded over {MAX_RECORD_COUNT}') put_record_batches.append(records_to_reingest) records_to_reingest = [] if len(records_to_reingest) > 0: # add the last batch put_record_batches.append(records_to_reingest) # iterate and call putRecordBatch for each group records_reingested_already = 0 stream_arn = event['deliveryStreamArn'] region = stream_arn.split(':')[3] stream_name = stream_arn.split('/')[1] if len(put_record_batches) > 0: client = boto3.client('firehose', region_name=region) for record_batch in put_record_batches: put_records_to_firehose(stream_name, record_batch, client) records_reingested_already += len(record_batch) print(f'Reingested {records_reingested_already}/{total_records_to_be_reingested} records out of {len(event["records"])}') else: print('No records to be reingested') # Return records to Firehose return_records = { 'records': records } print(str(return_records)) return return_records # Transform method for temporary data def _create_reingestion_record(original_record): return {'data': base64.b64decode(original_record['data'])} def _get_reingestion_record(re_ingestion_record): return {'Data': re_ingestion_record['data']} 参考 Amazon Kinesis Firehose Data Transformation with AWS Lambda | AWS Compute Blog https://aws.amazon.com/jp/blogs/compute/amazon-kinesis-firehose-data-transformation-with-aws-lambda/ DynamoDB StreamsとKinesis Data Firehoseを使ったサーバーレスリアルタイムETL - Qiita https://qiita.com/kzk-maeda/items/6dd02b9b567a6dd063fd Amazon DynamoDB ストリームを使用して、順序付けされたデータをアプリケーション間でレプリケーションする方法 | Amazon Web Services ブログ https://aws.amazon.com/jp/blogs/news/how-to-perform-ordered-data-replication-between-applications-by-using-amazon-dynamodb-streams/ --- ### DynamoDBからkinesis firehose経由でS3に出力 date: 2022-05-04 url: https://zatoima.github.io/aws-dynamodb-to-s3-by-kinesis/ tags: AWS Kinesis Data Streamsの作成 Kinesis Data Firehoseの設定 DynamoDB側の設定 aws dynamodb create-table --table-name 'cities' \ --attribute-definitions '[{"AttributeName":"key","AttributeType": "S"}]' \ --key-schema '[{"AttributeName":"key","KeyType": "HASH"}]' \ --provisioned-throughput '{"ReadCapacityUnits": 5,"WriteCapacityUnits": 5}' DynamoDB側でデータ生成 aws dynamodb put-item --table-name cities --item '{ "population": { "N": "38164" }, "date_mod": { "S": "1950-6-22" }, "key": { "S": "t0924" }, "name": { "S": "足利" } }' aws dynamodb put-item --table-name cities --item '{ "population": { "N": "72391" }, "date_mod": { "S": "1950-8-30" }, "key": { "S": "t0925" }, "name": { "S": "日光" } }' aws dynamodb put-item --table-name cities --item '{ "population": { "N": "56148" }, "date_mod": { "S": "1950-9-7" }, "key": { "S": "t0926" }, "name": { "S": "下野" } }' S3側の出力(※一部抜粋) {"awsRegion":"ap-northeast-1","eventID":"1e84f1ca-438d-4837-a6bd-aa4592be6f8a","eventName":"MODIFY","userIdentity":null,"recordFormat":"application/json","tableName":"cities","dynamodb":{"ApproximateCreationDateTime":1651495525900,"Keys":{"key":{"S":"t0926"}},"NewImage":{"population":{"N":"54148"},"key":{"S":"t0926"},"name":{"S":"下野"},"date_mod":{"S":"1950-9-7"}},"OldImage":{"population":{"N":"56148"},"key":{"S":"t0926"},"name":{"S":"下野"},"date_mod":{"S":"1950-9-7"}},"SizeBytes":104},"eventSource":"aws:dynamodb"} --- ### Auroraの各バージョンのサポート期間 date: 2022-05-01 url: https://zatoima.github.io/aws-aurora-support-eol/ tags: AWS, Aurora ※2022/05/01時点。最新はリンク先へ Auroraマニュアル https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/Aurora.VersionPolicy.html?utm_source=pocket_mylist#Aurora.VersionPolicy.MajorVersionLifetime Amazon Aurora メジャーバージョンが利用可能な期間 マイナーバージョンの使用期間が最低12ヶ月となっているので特定メジャーバージョンが上記まで使えるというわけではなく、最新のメジャーバージョンの場合、上記の期間まで使えると認識していた方が良さそうである。 https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/Aurora.VersionPolicy.html?utm_source=pocket_mylist#Aurora.VersionPolicy.MinorVersionLifetime 特定のメジャーバージョン用の各 Amazon Aurora マイナーバージョンは、少なくとも 12 か月間利用可能にしています。この期間が終了すると、Aurora は、後続のデフォルトのマイナーバージョンに関し、自動マイナーバージョンアップグレードを適用する可能性があります。 参考:PostgreSQL The PostgreSQL Global Development Group supports a major version for 5 years after its initial release. After its five year anniversary, a major version will have one last minor release containing any fixes and will be considered end-of-life (EOL) and no longer supported. 最初のリリースから5年間メジャーバージョンをサポートしています。5周年を迎えた後、メジャーバージョンには修正を含む最後のマイナーリリースが1つあり、保守終了(EOL)と見なされ、サポートされなくなります。 https://www.postgresql.org/support/versioning/ 参考:MySQL https://www.oracle.com/us/support/library/lifetime-support-technology-069183.pdf --- ### Hugo wowchemy(旧Academic)のcustom.scssのカスタマイズ date: 2022-04-22 url: https://zatoima.github.io/other-hugo-wowchemy-academic-custome/ tags: その他 高度なスタイルのカスタマイズが必要な場合は、既存のスタイルをオーバーライドしたり、強化するための CSS コード を記述することが可能 assets/scss/ フォルダがない場合は作成する。 assets/scss/ フォルダの中に custom.scss という名前のファイルを作成する。 作成したファイルにカスタムCSSコードを追加し、Hugoを再実行して変更を確認する。 .article-container { width: 100%; max-width: 1000px; min-width: 500px; margin-right: auto; margin-left: auto; } h1, h2, h3, h4, h5, h6 { margin-top: 1.7rem; margin-bottom: 0.3rem; font-weight: 700; } img { max-width: 100%; height: auto; vertical-align: bottom; } body, h1, h2, h3, h4, h5, h6, .navbar-custom { font-family: Helvetica,"Sawarabi Gothic",Meiryo,"メイリオ","Hiragino Kaku Gothic ProN", "ヒラギノ角ゴ ProN",YuGothic,"游ゴシック",Arial,sans-serif; } article h2 { padding: .5em .75em; border-left: 14px solid #E5E5E5; background-color: #f6f6f6; } article h3 { position: relative; padding: .25em 0 .5em .75em; border-left: 12px solid #E5E5E5; } article h3::after { position: absolute; left: 0; bottom: 0; content: ''; width: 100%; height: 0; border-bottom: 1px solid #E5E5E5; } article h4 { padding: .25em 0 .25em .75em; border-left: 10px solid #E5E5E5; } Extending Wowchemy | Wowchemy: Free, No Code Website Builder for Hugo themes Customize style (CSS) To personalize Wowchemy, you can choose a colour theme and font set in config/_default/params.yaml. For further personalization, you can create your own colour theme and font theme. If advanced style customization is required, CSS code can be written to override or enhance the existing styles: Create the assets/scss/ folder if it doesn’t exist Create a file named custom.scss in the assets/scss/ folder Add your custom CSS code to the file you created and re-run Hugo to view changes --- ### Aurora PostgreSQLのDB監査方式(Database Activity Streams or pgaudit?) date: 2022-04-16 url: https://zatoima.github.io/aws-aurora-postgresql-audit/ tags: AWS, Aurora, PostgreSQL 特徴 pgaudit PostgreSQL の拡張機能 PostgreSQL ログに混在して出力(Auroraの場合はCloudWatchにも出力) セッション監査/オブジェクト監査/DML・DDLを指定して対象の監査を絞ることが出来る 取得される情報サンプル 2020-11-13 08:06:24 UTC:10.0.1.123(50322):audit_user1@auditdb:[24298]:LOG: AUDIT: SESSION,1,2,DDL,CREATE TABLE AS,,,"CREATE TABLE t1 AS SELECT num a ,'1' b ,to_char(num,'FM00000') c ,current_timestamp d FROM generate_series(1,10000000) num ;",<none> 2020-11-13 08:07:36 UTC:10.0.1.123(50322):audit_user1@auditdb:[24298]:LOG: AUDIT: SESSION,2,1,READ,SELECT,TABLE,public.t1,select count(*) from t1;,<none> 2020-11-13 08:07:36 UTC::@:[32064]:LOG: AUDIT: SESSION,1,1,READ,SELECT,TABLE,public.t1,select count(*) from t1;,<none> 使用上の注意としてはパフォーマンス影響がある。下記はGithubから Depending on settings, it is possible for pgAudit to generate an enormous volume of logging. Be careful to determine exactly what needs to be audit logged in your environment to avoid logging too much. For example, when working in an OLAP environment it would probably not be wise to audit log inserts into a large fact table. The size of the log file will likely be many times the actual data size of the inserts because the log file is expressed as text. Since logs are generally stored with the OS this may lead to disk space being exhausted very quickly. In cases where it is not possible to limit audit logging to certain tables, be sure to assess the performance impact while testing and allocate plenty of space on the log volume. This may also be true for OLTP environments. Even if the insert volume is not as high, the performance impact of audit logging may still noticeably affect latency. 訳 設定によっては、pgAuditが膨大な量のログを生成する可能性があります。ロギングが多すぎないように、環境に監査ログを記録する必要があるものを正確に判断するように注意してください。 たとえば、OLAP環境で作業している場合、大きなファクトテーブルへのログ挿入を監査することはおそらく賢明ではありません。ログファイルはテキストとして表現されるため、ログファイルのサイズは挿入物の実際のデータサイズの何倍にもなる可能性があります。ログは通常OSに保存されるため、ディスク容量がすぐに使い果たされる可能性があります。監査ログを特定のテーブルに制限できない場合は、テスト中にパフォーマンスへの影響を評価し、ログボリュームに十分なスペースを割り当てるようにしてください。これは、OLTP環境にも当てはまる可能性があります。挿入量がそれほど多くない場合でも、監査ログのパフォーマンスへの影響がレイテンシーに著しく影響する可能性があります。 参考リンク https://github.com/pgaudit/pgaudit Database Activity Streams ほぼリアルタイムのデータを保存可能 職務分離が可能 DBAとセキュリティ担当がいたとして監査はセキュリティ担当だけが確認とかが出来る 同期モードと非同期モードが存在する。どちらも一長一短あって悩ましいところ。 非同期モード - データベースセッションでアクティビティストリーミングイベントが生成されると、セッションは直ちに通常のアクティビティに戻ります。アクティビティストリーミングイベントは、バックグラウンドで永続的なレコードになります。バックグラウンドタスクでエラーが発生した場合は、RDS イベントが送信されます。このイベントは、アクティビティストリーミングのイベントレコードが失われた可能性がある時間枠のスタートと終了を示します。 非同期モードでは、アクティビティストリーミングの精度よりもデータベースのパフォーマンスが優先されます。 同期モード - データベースセッションでアクティビティストリーミングイベントが生成されると、そのイベントが永続化されるまで、セッションによってその他のアクティビティはブロックされます。何らかの理由でイベントを永続化できない場合、データベースセッションは通常のアクティビティに戻ります。ただし、アクティビティストリーミングレコードがしばらくの間失われる可能性があることを示す RDS イベントが送信されます。システムが正常な状態に戻ったら、2 番目の RDS イベントが送信されます。 同期モードでは、データベースパフォーマンスよりもアクティビティストリーミングの精度が優先されます。 Kinesis ストリーミング分の追加料金が必要 取得出来る情報はマニュアルを確認 https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/DBActivityStreams.Monitoring.html Kinesis経由で3rd Partyの監視ツールやS3に出力することが出来る。S3に出力される場合、json形式なので可視化やSQLで分析するようなことが必要になってくるはず。 Aurora - DAS - Kinesis Stream - Kinesis Firehose - Lamdbaで復号化 - S3出力 という流れにする必要がある https://dev.classmethod.jp/articles/aurora-postgresql-audit-with-data-activity-stream/ AWSだけでやる場合、分析するためのAthenaやQuickSightの考慮が別途必要。 取得される情報サンプル { "type":"DatabaseActivityMonitoringRecords", "version":"1.1", "databaseActivityEvents": { "type":"DatabaseActivityMonitoringRecord", "clusterId":"cluster-4HNY5V4RRNPKKYB7ICFKE5JBQQ", "instanceId":"db-FZJTMYKCXQBUUZ6VLU7NW3ITCM", "databaseActivityEventList":[ { "startTime": "2019-05-24 00:36:54.403455+00", "logTime": "2019-05-24 00:36:54.494235+00", "statementId": 2, "substatementId": 1, "objectType": null, "command": "CREATE TABLE", "objectName": null, "databaseName": "postgres", "dbUserName": "rdsadmin", "remoteHost": "172.31.3.195", "remotePort": "34534", "sessionId": "5ce73c6f.7e64", "rowCount": null, "commandText": "create table my_table (id serial primary key, name varchar(32));", "paramList": [], "pid": 32356, "clientApplication": "psql", "exitCode": null, "class": "DDL", "serverVersion": "2.3.1", "serverType": "PostgreSQL", "serviceName": "Amazon Aurora PostgreSQL-Compatible edition", "serverHost": "172.31.3.192", "netProtocol": "TCP", "dbProtocol": "Postgres 3.0", "type": "record", "errorMessage": null } ] }, "key":"decryption-key" } 参考リンク https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/DBActivityStreams.html 結論 要件次第だが、特になければ次の通りが良いと思った pgauditを使う場合 DASの追加費用が高く感じる、同期モード・非同期モードの仕様が受け入れられない、AWSだけでやる場合の追加設定の考慮から、オンプレPostgreSQLと同様の監査方式を採用したい、オンプレPostgreSQLで実績が多いpgauditを使いたい場合、重要テーブルだけ監査を取りたいとかであればpgaudit DAS(Database Activity Streams) リアルタイム性を追求したい、職務分離をしたい、及びpgauditで全テーブル情報を取得してパフォーマンスIssueが発生してDASの非同期モードで負荷を少なく取得したい、様々なメトリクスを取得したい等があった場合 Appendix:簡易性能検証 パフォーマンスの差異も気になるので、pgbenchを使って検証してみた。N=1の結果なのであまり参考にならないかもしれない。実際のワークロードでどうなるかを見てください、というお約束。 32クライアントからpgbenchを実行して300秒実行し続けた結果を確認。 #ベンチマークテスト create database pgbench; pgbench -i -s 1000 -U postgres -h aurorapgsqlv1.cluster-xxxxxxx.ap-northeast-1.rds.amazonaws.com -d pgbench pgbench -r -c 32 -T 300 -U postgres -h aurorapgsqlv1.cluster-xxxxxxx.ap-northeast-1.rds.amazonaws.com pgbench 結果サマリ 負荷が低かったのかDAS(同期モード) 有効化を除く、ほぼ劣化しなかったという結果に。オンプレPostgreSQLでpgauditを有効化にした際にはもうちょっと劣化した記憶があるけど、今回のケースではほぼ劣化してなかった DB監査設定無し DAS(同期モード) 有効化 DAS(非同期モード) 有効化 pgaudit トランザクション数 548204 400485 533808 553199 平均レイテンシ 17.477 ms 23.922 ms 17.948 ms 17.319 ms tps 1831.0 1337.7 1783.0 1847.7 DB監査を1とした場合の劣化率 100% 137% 103% 99% DB監査設定無し [ec2-user@bastin ~]$ pgbench -i -s 1000 -U postgres -h aurorapgsqlv1.cluster-xxxxxxx.ap-northeast-1.rds.amazonaws.com -d pgbench dropping old tables... creating tables... generating data (client-side)... 100000000 of 100000000 tuples (100%) done (elapsed 113.86 s, remaining 0.00 s) vacuuming... creating primary keys... done in 204.96 s (drop tables 0.66 s, create tables 0.05 s, client-side generate 134.28 s, vacuum 36.71 s, primary keys 33.27 s). [ec2-user@bastin ~]$ [ec2-user@bastin ~]$ pgbench -r -c 32 -T 300 -U postgres -h aurorapgsqlv1.cluster-xxxxxxx.ap-northeast-1.rds.amazonaws.com pgbench pgbench (14.2, server 13.6) starting vacuum...end. transaction type: <builtin: TPC-B (sort of)> scaling factor: 1000 query mode: simple number of clients: 32 number of threads: 1 duration: 300 s number of transactions actually processed: 548204 latency average = 17.477 ms initial connection time = 613.275 ms tps = 1830.980993 (without initial connection time) statement latencies in milliseconds: 0.000 \set aid random(1, 100000 * :scale) 0.000 \set bid random(1, 1 * :scale) 0.000 \set tid random(1, 10 * :scale) 0.000 \set delta random(-5000, 5000) 1.895 BEGIN; 2.015 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid; 1.939 SELECT abalance FROM pgbench_accounts WHERE aid = :aid; 1.983 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid; 2.045 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid; 1.916 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP); 5.610 END; [ec2-user@bastin ~]$ PI Kinesis DAS(同期モード) 有効化 [ec2-user@bastin ~]$ pgbench -i -s 1000 -U postgres -h aurorapgsqlv1.cluster-xxxxxxx.ap-northeast-1.rds.amazonaws.com -d pgbench dropping old tables... creating tables... generating data (client-side)... 100000000 of 100000000 tuples (100%) done (elapsed 106.98 s, remaining 0.00 s) vacuuming... creating primary keys... done in 209.44 s (drop tables 0.65 s, create tables 0.06 s, client-side generate 136.14 s, vacuum 34.68 s, primary keys 37.90 s). [ec2-user@bastin ~]$ [ec2-user@bastin ~]$ pgbench -r -c 32 -T 300 -U postgres -h aurorapgsqlv1.cluster-xxxxxxx.ap-northeast-1.rds.amazonaws.com pgbench pgbench (14.2, server 13.6) starting vacuum...end. transaction type: <builtin: TPC-B (sort of)> scaling factor: 1000 query mode: simple number of clients: 32 number of threads: 1 duration: 300 s number of transactions actually processed: 400485 latency average = 23.922 ms initial connection time = 636.947 ms tps = 1337.700718 (without initial connection time) statement latencies in milliseconds: 0.000 \set aid random(1, 100000 * :scale) 0.000 \set bid random(1, 1 * :scale) 0.000 \set tid random(1, 10 * :scale) 0.000 \set delta random(-5000, 5000) 2.751 BEGIN; 2.942 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid; 2.897 SELECT abalance FROM pgbench_accounts WHERE aid = :aid; 2.909 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid; 2.991 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid; 2.808 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP); 6.548 END; [ec2-user@bastin ~]$ PI 明確に他のケースでは出ていないような待機イベントが発生している Kinesis DAS(非同期モード) 有効化 [ec2-user@bastin ~]$ pgbench -i -s 1000 -U postgres -h aurorapgsqlv1.cluster-xxxxxxx.ap-northeast-1.rds.amazonaws.com -d pgbench dropping old tables... creating tables... generating data (client-side)... 100000000 of 100000000 tuples (100%) done (elapsed 107.02 s, remaining 0.00 s) vacuuming... creating primary keys... done in 201.66 s (drop tables 0.65 s, create tables 0.04 s, client-side generate 128.15 s, vacuum 36.05 s, primary keys 36.76 s). [ec2-user@bastin ~]$ pgbench -r -c 32 -T 300 -U postgres -h aurorapgsqlv1.cluster-xxxxxxx.ap-northeast-1.rds.amazonaws.com pgbench pgbench (14.2, server 13.6) starting vacuum...end. transaction type: <builtin: TPC-B (sort of)> scaling factor: 1000 query mode: simple number of clients: 32 number of threads: 1 duration: 300 s number of transactions actually processed: 533808 latency average = 17.948 ms initial connection time = 622.183 ms tps = 1782.959790 (without initial connection time) statement latencies in milliseconds: 0.000 \set aid random(1, 100000 * :scale) 0.000 \set bid random(1, 1 * :scale) 0.000 \set tid random(1, 10 * :scale) 0.000 \set delta random(-5000, 5000) 1.933 BEGIN; 2.082 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid; 1.995 SELECT abalance FROM pgbench_accounts WHERE aid = :aid; 2.057 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid; 2.102 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid; 1.966 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP); 5.746 END; [ec2-user@bastin ~]$ PI Kinesis pgaudit [ec2-user@bastin ~]$ pgbench -i -s 1000 -U postgres -h aurorapgsqlv1.cluster-xxxxxxx.ap-northeast-1.rds.amazonaws.com -d pgbench dropping old tables... creating tables... generating data (client-side)... 100000000 of 100000000 tuples (100%) done (elapsed 134.45 s, remaining 0.00 s) vacuuming... creating primary keys... done in 233.72 s (drop tables 0.25 s, create tables 0.06 s, client-side generate 155.32 s, vacuum 35.62 s, primary keys 42.47 s). [ec2-user@bastin ~]$ [ec2-user@bastin ~]$ [ec2-user@bastin ~]$ pgbench -r -c 32 -T 300 -U postgres -h aurorapgsqlv1.cluster-xxxxxxx.ap-northeast-1.rds.amazonaws.com pgbench pgbench (14.2, server 13.6) starting vacuum...end. transaction type: <builtin: TPC-B (sort of)> scaling factor: 1000 query mode: simple number of clients: 32 number of threads: 1 duration: 300 s number of transactions actually processed: 553199 latency average = 17.319 ms initial connection time = 620.244 ms tps = 1847.681325 (without initial connection time) statement latencies in milliseconds: 0.000 \set aid random(1, 100000 * :scale) 0.000 \set bid random(1, 1 * :scale) 0.000 \set tid random(1, 10 * :scale) 0.000 \set delta random(-5000, 5000) 1.832 BEGIN; 1.997 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid; 1.897 SELECT abalance FROM pgbench_accounts WHERE aid = :aid; 1.950 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid; 2.010 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid; 1.873 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP); 参考 Part 1: Audit Aurora PostgreSQL databases using Database Activity Streams and pgAudit | AWS Database Blog https://aws.amazon.com/jp/blogs/database/part-1-audit-aurora-postgresql-databases-using-database-activity-streams-and-pgaudit/ Part 2: Audit Aurora PostgreSQL databases using Database Activity Streams and pgAudit | AWS Database Blog https://aws.amazon.com/jp/blogs/database/part-2-audit-aurora-postgresql-databases-using-database-activity-streams-and-pgaudit/ --- ### サーバ側と通信するCipher suite (暗号スイート) の調査方法 date: 2022-04-14 url: https://zatoima.github.io/other-cipher-suite-confirm/ tags: AWS, その他 備忘のためのメモ。今回は例としてS3のs3.amazonaws.comに対して色々と情報を見たいと思います。 暗号スイートとは? こちらのサイトがわかりやすかったです。 https://pkiwithadcs.com/cipher_suite/ 利用可能な暗号スイートの確認 nmap --script ssl-enum-ciphers -p 443 s3.amazonaws.com [ec2-user@bastin ~]$ nmap --script ssl-enum-ciphers -p 443 s3.amazonaws.com Starting Nmap 6.40 ( http://nmap.org ) at 2022-04-12 11:51 JST Nmap scan report for s3.amazonaws.com (52.217.129.136) Host is up (0.16s latency). rDNS record for 52.217.129.136: s3-1.amazonaws.com PORT STATE SERVICE 443/tcp open https | ssl-enum-ciphers: | TLSv1.0: | ciphers: | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - strong | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - strong | TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - strong | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - strong | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - strong | TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - strong | TLS_RSA_WITH_3DES_EDE_CBC_SHA - strong | TLS_RSA_WITH_AES_128_CBC_SHA - strong | TLS_RSA_WITH_AES_128_CBC_SHA256 - strong | TLS_RSA_WITH_AES_128_GCM_SHA256 - strong | TLS_RSA_WITH_AES_256_CBC_SHA - strong | TLS_RSA_WITH_AES_256_CBC_SHA256 - strong | TLS_RSA_WITH_AES_256_GCM_SHA384 - strong | compressors: | NULL | TLSv1.1: | ciphers: | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - strong | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - strong | TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - strong | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - strong | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - strong | TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - strong | TLS_RSA_WITH_3DES_EDE_CBC_SHA - strong | TLS_RSA_WITH_AES_128_CBC_SHA - strong | TLS_RSA_WITH_AES_128_CBC_SHA256 - strong | TLS_RSA_WITH_AES_128_GCM_SHA256 - strong | TLS_RSA_WITH_AES_256_CBC_SHA - strong | TLS_RSA_WITH_AES_256_CBC_SHA256 - strong | TLS_RSA_WITH_AES_256_GCM_SHA384 - strong | compressors: | NULL | TLSv1.2: | ciphers: | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - strong | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - strong | TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - strong | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - strong | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - strong | TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - strong | TLS_RSA_WITH_3DES_EDE_CBC_SHA - strong | TLS_RSA_WITH_AES_128_CBC_SHA - strong | TLS_RSA_WITH_AES_128_CBC_SHA256 - strong | TLS_RSA_WITH_AES_128_GCM_SHA256 - strong | TLS_RSA_WITH_AES_256_CBC_SHA - strong | TLS_RSA_WITH_AES_256_CBC_SHA256 - strong | TLS_RSA_WITH_AES_256_GCM_SHA384 - strong | compressors: | NULL |_ least strength: strong Nmap done: 1 IP address (1 host up) scanned in 7.09 seconds [ec2-user@bastin ~]$ SSL Server Testで確認 どの暗号スイートを使うのかの優先順位がわかる https://www.ssllabs.com/ssltest/analyze.html?d=s3.amazonaws.com S3に対して実際に通信を行う TLSv1.2のECDHE-RSA-AES128-GCM-SHA256を使って通信をしているようだ。 [ec2-user@bastin ~]$ openssl s_client -connect s3.amazonaws.com:443 < /dev/null CONNECTED(00000003) depth=2 C = US, O = Amazon, CN = Amazon Root CA 1 verify return:1 depth=1 C = US, O = Amazon, OU = Server CA 1B, CN = Amazon verify return:1 depth=0 CN = s3.amazonaws.com verify return:1 --- Certificate chain 0 s:/CN=s3.amazonaws.com ~省略~ --- No client certificate CA names sent Peer signing digest: SHA256 Server Temp Key: ECDH, P-256, 256 bits --- SSL handshake has read 5893 bytes and written 415 bytes --- New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1.2 Cipher : ECDHE-RSA-AES128-GCM-SHA256 Session-ID: 76E616AE11A2D6B01B11496893D0D0B966E0980757F14B7397D9A1C0FB3C1512 Session-ID-ctx: Master-Key: 588AB3813C66F79A3874BF67F4D11EC3F12B3FBC25C317C384EC111119B9E854D570DCE2DCEA7832D25E70E4AD1AF99F Key-Arg : None Krb5 Principal: None PSK identity: None PSK identity hint: None Start Time: 1649731926 Timeout : 300 (sec) Verify return code: 0 (ok) --- DONE 暗号スイート名 と OpenSSL での名称の対応表 opensslと一般的な暗号スイート名は一致していないので対応表を見つつ、これはどれだ?というのを見つける必要がある https://www.ipa.go.jp/security/ipg/documents/tls_cipher_suite_config_20200707.pdf TLS 暗号設定 暗号スイートの設定例 1.1.3. 一般的な名称と OpenSSL での名称の対応表 --- ### S3のパブリックアクセスに関するブロックパブリックアクセスとバケットポリシーの関係 date: 2022-04-10 url: https://zatoima.github.io/aws-s3-public-access-about-message-policy/ tags: AWS はじめに S3のパブリックアクセスについて下記4つのステータスを確認したので整理してみる。 非公開のバケットとオブジェクト オブジェクトは公開することができます 公開 このアカウントの認証ユーザのみ 1.非公開のバケットとオブジェクト 下記状態の場合、非公開のバケットとオブジェクトと表示される ブロックパブリックアクセスをオン バケットポリシーで明示的なアクセスを許可していない 2.オブジェクトは公開することができます 下記状態の場合、オブジェクトは公開することができますと表示される。当初、この表示の場合、パブリックアクセスが可能と思っていたが、明示的にバケットポリシーの変更が必要な模様。日本語的にもパブリックアクセス可能なように思えたが、実際にはアクセスできない。 ブロックパブリックアクセスをオフ バケットポリシーで明示的なアクセスを許可していない 3.公開 下記状態の場合、公開と表示される。 ブロックパブリックアクセスをオフ バケットポリシーで明示的なアクセスを許可を行う 例: { "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": [ "s3:GetObject" ], "Resource": [ "arn:aws:s3:::s3-public-test-1/*" ] } ] } 4.このアカウントの認証ユーザのみ 下記状態の場合、このアカウントの認証ユーザのみと表示される。 ブロックパブリックアクセスをオン バケットポリシーで明示的なアクセスを許可を行う --- ### Amplifyを使用してCognitoテスト環境を構成する date: 2022-03-18 url: https://zatoima.github.io/aws-cognito-setting-amplify/ tags: AWS はじめに 本記事はCognitoの実機確認を行いたかったため、こちらのCognito実行までを実行している作業メモです。手順自体は下記を見た方が絶対にわかりやすいです。 https://amplify-sns.workshop.aws/ja/ 確認事前準備 バージョン確認 Node.js、npm Amplify CLIではNode.jsで10.x、npmでは6.x以降のバージョンが推奨らしい [ec2-user@bastin ~]$ node -v; npm -v v17.7.1 8.5.2 Java [ec2-user@bastin ~]$ java -version openjdk version "1.8.0_312" OpenJDK Runtime Environment (build 1.8.0_312-b07) OpenJDK 64-Bit Server VM (build 25.312-b07, mixed mode) Amplify CLIのインストール [ec2-user@bastin ~]$ npm install -g @aws-amplify/cli@4.45.0 ~省略~ [ec2-user@bastin ~]$ amplify version Initializing new Amplify CLI version... Done initializing new version. Scanning for plugins... Plugin scan successful 4.45.0 Amplify CLIの設定 amplify configure [ec2-user@bastin ~]$ amplify configure Follow these steps to set up access to your AWS account: Sign in to your AWS administrator account: https://console.aws.amazon.com/ Press Enter to continue Specify the AWS Region ? region: ap-northeast-1 Specify the username of the new IAM user: ? user name: amplify-wJAim Complete the user creation using the AWS console https://console.aws.amazon.com/iam/home?region=ap-northeast-1#/users$new?step=final&accessKey&userNames=amplify-wJAim&permissionType=policies&policies=arn:aws:iam::aws:policy%2FAdministratorAccess Press Enter to continue Enter the access key of the newly created user: ? accessKeyId: ******************** ? secretAccessKey: **************************************** This would update/create the AWS Profile in your local machine ? Profile Name: default Successfully set up the new user. [ec2-user@bastin ~]$ 作業ディレクトリの作成 mkdir amplify-sns-workshop cd amplify-sns-workshop npx create-react-app boyaki cd boyaki Amplifyの初期化 amplify init [ec2-user@bastin boyaki]$ amplify init Note: It is recommended to run this command from the root of your app directory ? Enter a name for the project boyaki ? Enter a name for the environment production ? Choose your default editor: Vim (via Terminal, Mac OS only) ? Choose the type of app that you're building javascript Please tell us about your project ? What javascript framework are you using react ? Source Directory Path: src ? Distribution Directory Path: build ? Build Command: npm run-script build ? Start Command: npm run-script start Using default provider awscloudformation ? Select the authentication method you want to use: AWS profile For more information on AWS Profiles, see: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html ? Please choose the profile you want to use default Adding backend environment production to AWS Amplify Console app: d23637fuj8pa65 ⠧ Initializing project in the cloud... ~省略~ 環境のテスト development server起動後に、http://localhost:3000 や http://<PublicIP>:3000にアクセスする [ec2-user@bastin boyaki]$ npm start > boyaki@0.1.0 start > react-scripts start (node:24767) [DEP_WEBPACK_DEV_SERVER_ON_AFTER_SETUP_MIDDLEWARE] DeprecationWarning: 'onAfterSetupMiddleware' option is deprecated. Please use the 'setupMiddlewares' option. (Use `node --trace-deprecation ...` to show where the warning was created) (node:24767) [DEP_WEBPACK_DEV_SERVER_ON_BEFORE_SETUP_MIDDLEWARE] DeprecationWarning: 'onBeforeSetupMiddleware' option is deprecated. Please use the 'setupMiddlewares' option. Starting the development server... Compiled successfully! You can now view boyaki in the browser. Local: http://localhost:3000 On Your Network: http://10.0.1.31:3000 Note that the development build is not optimized. To create a production build, use npm run build. assets by path static/ 1.49 MiB asset static/js/bundle.js 1.48 MiB [emitted] (name: main) 1 related asset asset static/js/node_modules_web-vitals_dist_web-vitals_js.chunk.js 6.92 KiB [emitted] 1 related asset asset static/media/logo.6ce24c58023cc2f8fd88fe9d219db6c6.svg 2.57 KiB [emitted] (auxiliary name: main) asset index.html 1.67 KiB [emitted] asset asset-manifest.json 546 bytes [emitted] runtime modules 31.3 KiB 15 modules modules by path ./node_modules/ 1.35 MiB 99 modules modules by path ./src/ 18.1 KiB modules by path ./src/*.css 8.82 KiB ./src/index.css 2.72 KiB [built] [code generated] ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[1].oneOf[5].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].oneOf[5].use[2]!./node_modules/source-map-loader/dist/cjs.js!./src/index.css 1.37 KiB [built] [code generated] ./src/App.css 2.72 KiB [built] [code generated] ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[1].oneOf[5].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].oneOf[5].use[2]!./node_modules/source-map-loader/dist/cjs.js!./src/App.css 2 KiB [built] [code generated] modules by path ./src/*.js 5.7 KiB ./src/index.js 1.8 KiB [built] [code generated] ./src/App.js 2.51 KiB [built] [code generated] ./src/reportWebVitals.js 1.39 KiB [built] [code generated] ./src/logo.svg 3.61 KiB [built] [code generated] webpack 5.70.0 compiled successfully in 7242 ms 認証機能の追加 全てデフォルトで良い。 cd /home/ec2-user/amplify-sns-workshop/boyaki amplify add auth [ec2-user@bastin boyaki]$ amplify add auth Using service: Cognito, provided by: awscloudformation The current configured provider is Amazon Cognito. Do you want to use the default authentication and security configuration? Default configuration Warning: you will not be able to edit these selections. How do you want users to be able to sign in? Username Do you want to configure advanced settings? No, I am done. Successfully added auth resource boyaki9b531430 locally Some next steps: "amplify push" will build all your local backend resources and provision it in the cloud "amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud ステータスの確認 [ec2-user@bastin boyaki]$ amplify status Current Environment: production | Category | Resource name | Operation | Provider plugin | | -------- | -------------- | --------- | ----------------- | | Auth | boyaki9b531430 | Create | awscloudformation | 変更の反映 数分掛かる。正常に完了するとCognitoが設定されている状態となる amplify push [ec2-user@bastin boyaki]$ amplify push ✔ Successfully pulled backend environment production from the cloud. Current Environment: production | Category | Resource name | Operation | Provider plugin | | -------- | -------------- | --------- | ----------------- | | Auth | boyaki9b531430 | Create | awscloudformation | ? Are you sure you want to continue? Yes ⠼ Updating resources in the cloud. This may take a few minutes... UPDATE_IN_PROGRESS amplify-boyaki-production-211642 AWS::CloudFormation::Stack Tue Mar 15 2022 21:25:11 GMT+0900 (Coordinated Universal Time) User Initiated ⠧ Updating resources in the cloud. This may take a few minutes... ~中略~ ✔ All resources are updated in the cloud 認証機能のフロントエンドへの実装 npm install --save aws-amplify@3.3.14 @aws-amplify/ui-react@0.2.34 実行時に、npm ERR! peer react@"^16.7.0" from @aws-amplify/ui-react@0.2.34が出る場合は、Reactのバージョンを16系に変更する必要があり、package.jsonファイルを以下の内容に書き換える必要がある模様。下記は手順。実行後に再度上記のnpm install --save ~を実行 { "name": "boyaki", "version": "0.1.0", "private": true, "dependencies": { "@testing-library/jest-dom": "^5.14.1", "@testing-library/react": "^11.2.7", "@testing-library/user-event": "^12.8.3", "react": "16.10.0", "react-dom": "16.10.0", "react-scripts": "4.0.3", "web-vitals": "^1.1.2" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, "eslintConfig": { "extends": [ "react-app", "react-app/jest" ] }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] } } npmのインストール npm install ./src/App.jsファイルの中身の変更 下記に置き換える vi ./src/App.js import React from 'react'; import Amplify from 'aws-amplify'; import { AmplifyAuthenticator, AmplifySignUp, AmplifySignOut } from '@aws-amplify/ui-react'; import { AuthState, onAuthUIStateChange } from '@aws-amplify/ui-components'; import awsconfig from './aws-exports'; Amplify.configure(awsconfig); const App = () => { const [authState, setAuthState] = React.useState(); const [user, setUser] = React.useState(); React.useEffect(() => { return onAuthUIStateChange((nextAuthState, authData) => { setAuthState(nextAuthState); setUser(authData) }); }, []); return authState === AuthState.SignedIn && user ? ( <div className="App"> <div>Hello, {user.username}</div> <AmplifySignOut /> </div> ) : ( <AmplifyAuthenticator> <AmplifySignUp slot="sign-up" formFields={[ { type: "username" }, { type: "password" }, { type: "email" } ]} /> </AmplifyAuthenticator> ); } export default App; ここまで来てnpm startでdevelopment serverを起動したところ下記のエラーが発生 ERROR in ./src/App.js 43:35-48 export 'AmplifySignUp' (imported as 'AmplifySignUp') was not found in '@aws-amplify/ui-react' (possible exports: Alert, AmplifyProvider, Authenticator ~中略~ 下記を見てreactのバージョンをダウングレードしたところ正常にいった。 ‘AmplifySignOut’ is not exported from ‘@aws-amplify/ui-react’.を解消する - Qiita npm list --depth=0 npm remove @aws-amplify/ui-react npm install @aws-amplify/ui-react@1.2.25 npm list --depth=0 [ec2-user@bastin boyaki]$ npm list --depth=0 boyaki@0.1.0 /home/ec2-user/amplify-sns-workshop/boyaki ├── @aws-amplify/ui-react@2.10.0 ├── @testing-library/jest-dom@5.16.2 ├── @testing-library/react@12.1.4 ├── @testing-library/user-event@13.5.0 ├── aws-amplify@4.3.16 ├── react-dom@17.0.2 ├── react-scripts@5.0.0 ├── react@17.0.2 └── web-vitals@2.1.4 [ec2-user@bastin boyaki]$ [ec2-user@bastin boyaki]$ npm remove @aws-amplify/ui-react removed 93 packages, and audited 2351 packages in 12s 178 packages are looking for funding run `npm fund` for details 17 moderate severity vulnerabilities To address issues that do not require attention, run: npm audit fix To address all issues (including breaking changes), run: npm audit fix --force Run `npm audit` for details. [ec2-user@bastin boyaki]$ npm install @aws-amplify/ui-react@1.2.25 added 19 packages, and audited 2370 packages in 10s 178 packages are looking for funding run `npm fund` for details 17 moderate severity vulnerabilities To address issues that do not require attention, run: npm audit fix To address all issues (including breaking changes), run: npm audit fix --force Run `npm audit` for details. [ec2-user@bastin boyaki]$ [ec2-user@bastin boyaki]$ npm list --depth=0 boyaki@0.1.0 /home/ec2-user/amplify-sns-workshop/boyaki ├── @aws-amplify/ui-react@1.2.25 ├── @testing-library/jest-dom@5.16.2 ├── @testing-library/react@12.1.4 ├── @testing-library/user-event@13.5.0 ├── aws-amplify@4.3.16 ├── react-dom@17.0.2 ├── react-scripts@5.0.0 ├── react@17.0.2 └── web-vitals@2.1.4 Cognito側でもユーザプールが作成されていることを確認出来る。 環境の削除 $ amplify delete ? Are you sure you want to continue? This CANNOT be undone. (This will delete all the environments of the project from the clou d and wipe out all the local files created by Amplify CLI) Yes ⠋ Deleting resources from the cloud. This may take a few minutes... Deleting env:production ✔ Project deleted in the cloud Project deleted locally. --- ### AWS Config設定時の「設定を記録できる配信チャネルがありません。」を解消する date: 2022-03-16 url: https://zatoima.github.io/aws-config-delivery-channels-error/ tags: AWS 問題 AWS Configで記録を有効化しようとすると「設定を記録できる配信チャネルがありません。」が出力されて有効化出来ないケース 下記のように、配信チャネルが無い状態になっていると思われるので、配信チャネルを手動作成する。DeliveryChannelsが確かにnullになっている。 [ec2-user@bastin ~]$ aws configservice describe-delivery-channels { "DeliveryChannels": [] } [ec2-user@bastin ~]$ aws configservice describe-configuration-recorders { "ConfigurationRecorders": [ { "name": "default", "roleARN": "arn:aws:iam::xxxxxx:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig", "recordingGroup": { "allSupported": true, "includeGlobalResourceTypes": true, "resourceTypes": [] } } ] } 解決方法:配信チャネルの作成 配信チャネル作成後にConfigの再設定を行う [ec2-user@bastin ~]$ aws configservice put-delivery-channel --delivery-channel name=default,s3BucketName=config-bucket-xxxxxxxxxx --region ap-northeast-1 参考 put-delivery-channel — AWS CLI 1.22.73 Command Reference 設定確認 [ec2-user@bastin ~]$ aws configservice describe-delivery-channels { "DeliveryChannels": [ { "name": "default", "s3BucketName": "config-bucket-xxxxx" } ] } [ec2-user@bastin ~]$ aws configservice describe-configuration-recorders { "ConfigurationRecorders": [ { "name": "default", "roleARN": "arn:aws:iam::xxxx:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig", "recordingGroup": { "allSupported": true, "includeGlobalResourceTypes": true, "resourceTypes": [] } } ] } --- ### EMR Sparkのメモリ関連のパラメータ設定 date: 2022-03-13 url: https://zatoima.github.io/aws-emr-memory-parameter-settiong/ tags: AWS, EMR Sparkの全体像 Executorとかパーティションの概念のような前提となるようなSparkの構成要素 Apache Sparkの構成要素、概要、用語について | my opinion is my own Spark on EMRの基礎をおさらいする - Qiita Sparkのメモリ管理の全体像 Amazon EMR で Apache Spark アプリケーションのメモリをうまく管理するためのベストプラクティス | Amazon Web Services ブログ メモリ管理のパラメータ 上記ブログに記載があるspark.dynamicAllocation.enabledをFalseにした場合の各インスタンスタイプとノード数に合わせた各パラメータの計算。計算式についてはこのExcelに埋め込んである。黄色セル部分を各インスタンスタイプや実際の環境に合わせて変えれば自動計算してくれるはず。 あくまで初期サイジングとして実施すべきであって適宜チューニングの余地がありm特にパーティション数については実際に動かして決めるべき。 インスタンスタイプ r5.12xlarge m5.8xlarge vCPU 48 32 メモリ 384 128 ノード数 5 5 spark.executor.cores:エグゼキュータあたりの仮想コアの数 5 5 spark.executor.memory:Executorが使用するメモリのサイズ 9g 6g spark.yarn.executor.memoryOverhead:Executorが使用するメモリ分のオーバーヘッドのサイズ 1g 1g spark.driver.memory:Driverのために使用するメモリのサイズ 9g 6g spark.driver.cores:Driverのために使用する仮想コアの数 5 5 spark.executor.instances :インスタンスあたりのExecutorの数 44 29 spark.default.parallelism:Partition数のデフォルト値 440 290 その他のパラメータ その他パラメータについてはブログ側に記載されているパラメータと、Spark側のマニュアルと見比べつつ、必要なものついて設定すれば良いと思う。 [ { "Classification": "yarn-site", "Properties": { "yarn.nodemanager.vmem-check-enabled": "false", "yarn.nodemanager.pmem-check-enabled": "false" } }, { "Classification": "spark", "Properties": { "maximizeResourceAllocation": "false" } }, { "Classification": "spark-defaults", "Properties": { "spark.driver.memory": "39G", "spark.driver.cores": "5", "spark.executor.memory": "39G", "spark.executor.cores": "5", "spark.executor.instances": "14", "spark.executor.memoryOverhead": "5G", "spark.driver.memoryOverhead": "5G", "spark.default.parallelism": "140", "spark.sql.shuffle.partitions": "140", "spark.network.timeout": "800s", "spark.executor.heartbeatInterval": "60s", "spark.dynamicAllocation.enabled": "false", "spark.memory.fraction": "0.80", "spark.memory.storageFraction": "0.30", "spark.executor.extraJavaOptions": "-XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+G1SummarizeConcMark -XX:InitiatingHeapOccupancyPercent=35 -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:OnOutOfMemoryError='kill -9 %p'", "spark.driver.extraJavaOptions": "-XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+G1SummarizeConcMark -XX:InitiatingHeapOccupancyPercent=35 -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:OnOutOfMemoryError='kill -9 %p'", "spark.yarn.scheduler.reporterThread.maxFailures": "5", "spark.storage.level": "MEMORY_AND_DISK_SER", "spark.rdd.compress": "true", "spark.shuffle.compress": "true", "spark.shuffle.spill.compress": "true", "spark.serializer": "org.apache.spark.serializer.KryoSerializer" } } ] 参考資料 Apache Hadoop 3.3.1 – Using Memory Control in YARN Configuration - Spark 3.2.1 Documentation アプリケーションの設定 - Amazon EMR Amazon EMR で Apache Spark アプリケーションのメモリをうまく管理するためのベストプラクティス | Amazon Web Services ブログ --- ### RedshiftのPython UDFの同時実行数 date: 2022-03-03 url: https://zatoima.github.io/aws-redshift-python-udf-concurency/ tags: AWS, Redshift Python UDFとは スカラー Python UDF の作成 - Amazon Redshift Redshiftには、関数が呼び出されると実行され、単一値を返す Python プログラムを実行出来る。 Python UDFの作成自体はcreate funtionを使用する create OR REPLACE function testudfpython (a float, b float) returns float stable as $$ import time if a > b: c = a + b elif a < b: c = a * b else: return 0 return c $$ language plpythonu; テスト用テーブルの作成 drop table testtable; create table testtable(a numeric,b numeric,c numeric); insert into testtable values(1,1,1); insert into testtable values(2,4,6); insert into testtable values(4,8,12); mydb=# select * from testtable; a | b | c ---+---+---- 1 | 1 | 1 2 | 4 | 6 4 | 8 | 12 (3 rows) Python UDFの実行 select testudfpython(b,c) from testtable where a=4; select testudfpython(b,c) from testtable where a=2; 実行結果 mydb=# select testudfpython(b,c) from testtable where a=4; testudfpython --------------- 96 (1 row) mydb=# select testudfpython(b,c) from testtable where a=2; testudfpython --------------- 24 (1 row) Python UDFの制約 Amazon Redshift Python UDF には以下の制約がある。 Python UDF は、ネットワークにアクセスすることもファイルシステムに読み書きすることもできません。 ユーザーがインストールする Python ライブラリの合計サイズは 100 MB を超えられません。 1 つのクラスターで同時に実行できる Python UDF の数は、そのクラスターの合計同時実行レベルの 4 分の 1 に制限されています。たとえば、クラスターの同時実行レベルが 15 に設定されている場合は、最大で 3 つの UDF を同時に実行できます。この制限に達すると、UDF はワークロード管理キュー内で実行されるのを待ちます。SQL UDF に同時実行の制限はありません。詳細については、「ワークロード管理の実装」を参照してください。 Amazon Redshift で Python UDF を使用する場合、SUPER および HLLSKETCH データタイプはサポートされせん。 特に同時実行数に関してだが、マニュアルの記載を見ると同時実行数を設定した1/4まで実行出来るように見受けられるが、同時実行数を設定するのはManual WLMであり、デフォルトのWLMの場合がどうなのかは記載がない。 強制的にSleepするPython UDFを作成して複数クライアントから実行してみる。この状態のキューの状態も合わせて確認する。 create OR REPLACE function testudfpython (a float, b float) returns float stable as $$ import time time.sleep(90) if a > b: c = a + b elif a < b: c = a * b else: return 0 return c $$ language plpythonu; 確認結果① Auto WLMの場合で複数セッションからPython UDFを実行した場合、同時実行数は「1」のようだ。Sleepを90秒入れているため2つめのセッションで180秒掛かっている。 確認結果②:キューの状態とクエリの状態を確認 psql -h redshift-ra3.ciwori21oiel.ap-northeast-1.redshift.amazonaws.com -U benchuser -d mydb -p 5439 -f /home/ec2-user/amazon-redshift-utils/src/AdminScripts/queuing_queries.sql psql -h redshift-ra3.ciwori21oiel.ap-northeast-1.redshift.amazonaws.com -U benchuser -d mydb -p 5439 -f /home/ec2-user/amazon-redshift-utils/src/AdminScripts/top_queries.sql 該当するクエリは無し。あくまでPython UDFであり、SQLということでもないので上がってこないらしい。 確認結果③:マネージメントコンソールからのキューの状態 実行しているSQLとしては上がってくるが、キューに入るわけではないようだ。 結論 Auto WLMの場合、同時実行数は1となっている。複数クライアントから実行するようなPython UDFには注意が必要。(そもそも個人的にはデータベース側にロジックを持たせるのはあまり好きではない。こういうUDFやストアド等。) --- ### RedshiftのLambda UDFの設定 date: 2022-02-24 url: https://zatoima.github.io/aws-redshift-lamdba-udf-setting/ tags: AWS, Redshift Lamdba側の関数作成 小文字に変換する関数 import json def lambda_handler(event, context): print("Received event: " + json.dumps(event, indent=2)) print(json.dumps(event)) res = [x[0].lower() for x in event['arguments']] ret_json = json.dumps({"results": res}) return ret_json IAMロールの作成 IAMロールを用意してRedshiftクラスタにアタッチする https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/udf-creating-a-lambda-sql-udf.html#udf-lambda-authorization Lambda 用に IAM ロールを作成する { "Version": "2012-10-17", "Statement": [ { "Sid": "Invoke", "Effect": "Allow", "Action": [ "lambda:InvokeFunction" ], "Resource": "arn:aws:lambda:us-west-2:123456789012:function:my-function" } ] } Redshift側でLamdba udfの作成 CREATE OR REPLACE EXTERNAL FUNCTION f_lower_python(varchar) RETURNS varchar IMMUTABLE LAMBDA 'f_lower_python' IAM_ROLE 'arn:aws:iam::xxxxx:role/redshiftlf1'; 実行 mydb=# select f_lower_python(a) from test1 limit 10; f_lower_python ---------------- aaaa uidus aaaa uidus uidus aaaa uidus aaaa aaaa uidus (10 rows) --- ### EMRからS3にアップロードする date: 2022-02-22 url: https://zatoima.github.io/aws-emr-s3-upload/ tags: AWS, EMR HDFS上のファイルをS3にアップロードする時には下記の大きく2つの手段がある。この2つをざっくりコマンド叩いてみる。 hadoop fs -cp:HDFS上のファイル操作。S3に対してはマルチアップロードとなる模様。 hadoop distcp/s3-dist-cp:MapReduceを使用した分散処理。なお、s3-dist-cpはS3に特化して機能面が多い。 事前準備 テスト用ファイルの作成(1GBのファイル) head -c 1000m /dev/urandom > test1.txt head -c 1000m /dev/urandom > test2.txt head -c 1000m /dev/urandom > test3.txt hadoop fs -rm /user/hadoop/test*.txt hadoop fs -put test1.txt /user/hadoop/ hadoop fs -put test2.txt /user/hadoop/ hadoop fs -put test3.txt /user/hadoop/ hadoop fs -ls /user/hadoop/ HDFS上のファイル確認 [hadoop@ip-192-168-0-33 ~]$ hadoop fs -ls /user/hadoop/ SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/usr/lib/hadoop/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/usr/share/aws/emr/emrfs/lib/slf4j-log4j12-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory] Found 3 items -rw-r--r-- 1 hadoop hdfsadmingroup 1048576000 2022-02-03 07:05 /user/hadoop/test1.txt -rw-r--r-- 1 hadoop hdfsadmingroup 1048576000 2022-02-03 07:05 /user/hadoop/test2.txt -rw-r--r-- 1 hadoop hdfsadmingroup 1048576000 2022-02-03 07:05 /user/hadoop/test3.txt hadoop fs -cp [hadoop@ip-192-168-0-33 ~]$ hadoop fs -cp -f /user/hadoop/test1.txt s3://<S3バケット>/ SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/usr/lib/hadoop/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/usr/share/aws/emr/emrfs/lib/slf4j-log4j12-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory] 22/02/03 07:06:12 INFO s3n.MultipartUploadOutputStream: uploadPart: partNum 1 of 's3://<S3バケット>/test1.txt' from local file '/mnt1/s3/emrfs-5827993998494060058/0000000000', 134217728 bytes in 1498 ms, md5: uq4Pfvy+zC+aWVf01fhRtQ== md5hex: baae0f7efcbecc2f9a5957f4d5f851b5 22/02/03 07:06:12 INFO s3n.MultipartUploadOutputStream: uploadPart: partNum 2 of 's3://<S3バケット>/test1.txt' from local file '/mnt/s3/emrfs-9215835204334260739/0000000001', 134217728 bytes in 1321 ms, md5: GGb7qT4wl52ltofQ0SSMnQ== md5hex: 1866fba93e30979da5b687d0d1248c9d 22/02/03 07:06:13 INFO s3n.MultipartUploadOutputStream: uploadPart: partNum 3 of 's3://<S3バケット>/test1.txt' from local file '/mnt1/s3/emrfs-5827993998494060058/0000000002', 134217728 bytes in 1200 ms, md5: FAVMVJoyETUk9XHXYSTUew== md5hex: 14054c549a32113524f571d76124d47b 22/02/03 07:06:13 INFO s3n.MultipartUploadOutputStream: uploadPart: partNum 4 of 's3://<S3バケット>/test1.txt' from local file '/mnt/s3/emrfs-9215835204334260739/0000000003', 134217728 bytes in 1009 ms, md5: AVAEWiZHnQB7l8QhiwWhIg== md5hex: 0150045a26479d007b97c4218b05a122 22/02/03 07:06:14 INFO s3n.MultipartUploadOutputStream: uploadPart: partNum 5 of 's3://<S3バケット>/test1.txt' from local file '/mnt1/s3/emrfs-5827993998494060058/0000000004', 134217728 bytes in 1074 ms, md5: d4erSVSapJ8tfT/KPMm0ag== md5hex: 7787ab49549aa49f2d7d3fca3cc9b46a 22/02/03 07:06:15 INFO s3n.MultipartUploadOutputStream: uploadPart: partNum 6 of 's3://<S3バケット>/test1.txt' from local file '/mnt/s3/emrfs-9215835204334260739/0000000005', 134217728 bytes in 1079 ms, md5: mQElzOq2L+D6NgaM5io9wg== md5hex: 990125cceab62fe0fa36068ce62a3dc2 22/02/03 07:06:15 INFO s3n.MultipartUploadOutputStream: close closed:false s3://<S3バケット>/test1.txt 22/02/03 07:06:15 INFO s3n.MultipartUploadOutputStream: uploadPart: partNum 7 of 's3://<S3バケット>/test1.txt' from local file '/mnt1/s3/emrfs-5827993998494060058/0000000006', 134217728 bytes in 985 ms, md5: NpCzzQUQia4lZlXx4TtBxA== md5hex: 3690b3cd051089ae256655f1e13b41c4 22/02/03 07:06:16 INFO s3n.MultipartUploadOutputStream: uploadPart: partNum 8 of 's3://<S3バケット>/test1.txt' from local file '/mnt/s3/emrfs-9215835204334260739/0000000007', 109051904 bytes in 850 ms, md5: 4yBV8LAdE5MVZcTAjvl+/w== md5hex: e32055f0b01d13931565c4c08ef97eff 22/02/03 07:06:16 INFO dispatch.DefaultMultipartUploadDispatcher: Completed multipart upload of 8 parts 1048576000 bytes 22/02/03 07:06:16 INFO s3n.MultipartUploadOutputStream: close closed:true s3://<S3バケット>/test1.txt hadoop distcp [hadoop@ip-192-168-0-33 ~]$ time hadoop distcp /user/hadoop/test2.txt s3://<S3バケット>/ SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/usr/lib/hadoop/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/usr/share/aws/emr/emrfs/lib/slf4j-log4j12-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory] 22/02/03 07:07:45 INFO tools.OptionsParser: parseChunkSize: blocksperchunk false 22/02/03 07:07:47 INFO tools.DistCp: Input Options: DistCpOptions{atomicCommit=false, syncFolder=false, deleteMissing=false, ignoreFailures=false, overwrite=false, append=false, useDiff=false, useRdiff=false, fromSnapshot=null, toSnapshot=null, skipCRC=false, blocking=true, numListstatusThreads=0, maxMaps=20, mapBandwidth=100, sslConfigurationFile='null', copyStrategy='uniformsize', preserveStatus=[], preserveRawXattrs=false, atomicWorkPath=null, logPath=null, sourceFileListing=null, sourcePaths=[/user/hadoop/test2.txt], targetPath=s3://<S3バケット>/, targetPathExists=true, filtersFile='null', blocksPerChunk=0, copyBufferSize=8192, verboseLog=false} 22/02/03 07:07:47 INFO client.RMProxy: Connecting to ResourceManager at ip-192-168-0-33.ap-northeast-1.compute.internal/192.168.0.33:8032 22/02/03 07:07:47 INFO client.AHSProxy: Connecting to Application History server at ip-192-168-0-33.ap-northeast-1.compute.internal/192.168.0.33:10200 22/02/03 07:07:48 INFO tools.SimpleCopyListing: Paths (files+dirs) cnt = 1; dirCnt = 0 22/02/03 07:07:48 INFO tools.SimpleCopyListing: Build file listing completed. 22/02/03 07:07:48 INFO Configuration.deprecation: io.sort.mb is deprecated. Instead, use mapreduce.task.io.sort.mb 22/02/03 07:07:48 INFO Configuration.deprecation: io.sort.factor is deprecated. Instead, use mapreduce.task.io.sort.factor 22/02/03 07:07:48 INFO tools.DistCp: Number of paths in the copy list: 1 22/02/03 07:07:48 INFO tools.DistCp: Number of paths in the copy list: 1 22/02/03 07:07:48 INFO client.RMProxy: Connecting to ResourceManager at ip-192-168-0-33.ap-northeast-1.compute.internal/192.168.0.33:8032 22/02/03 07:07:48 INFO client.AHSProxy: Connecting to Application History server at ip-192-168-0-33.ap-northeast-1.compute.internal/192.168.0.33:10200 22/02/03 07:07:48 INFO mapreduce.JobSubmitter: number of splits:1 22/02/03 07:07:48 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1643867855502_0005 22/02/03 07:07:48 INFO conf.Configuration: resource-types.xml not found 22/02/03 07:07:48 INFO resource.ResourceUtils: Unable to find 'resource-types.xml'. 22/02/03 07:07:48 INFO resource.ResourceUtils: Adding resource type - name = memory-mb, units = Mi, type = COUNTABLE 22/02/03 07:07:48 INFO resource.ResourceUtils: Adding resource type - name = vcores, units = , type = COUNTABLE 22/02/03 07:07:48 INFO impl.YarnClientImpl: Submitted application application_1643867855502_0005 22/02/03 07:07:48 INFO mapreduce.Job: The url to track the job: http://ip-192-168-0-33.ap-northeast-1.compute.internal:20888/proxy/application_1643867855502_0005/ 22/02/03 07:07:48 INFO tools.DistCp: DistCp job-id: job_1643867855502_0005 22/02/03 07:07:48 INFO mapreduce.Job: Running job: job_1643867855502_0005 22/02/03 07:07:53 INFO mapreduce.Job: Job job_1643867855502_0005 running in uber mode : false 22/02/03 07:07:53 INFO mapreduce.Job: map 0% reduce 0% 22/02/03 07:08:00 INFO mapreduce.Job: map 100% reduce 0% 22/02/03 07:08:03 INFO mapreduce.Job: Job job_1643867855502_0005 completed successfully 22/02/03 07:08:03 INFO mapreduce.Job: Counters: 37 File System Counters FILE: Number of bytes read=0 FILE: Number of bytes written=224682 FILE: Number of read operations=0 FILE: Number of large read operations=0 FILE: Number of write operations=0 HDFS: Number of bytes read=436 HDFS: Number of bytes written=88 HDFS: Number of read operations=7 HDFS: Number of large read operations=0 HDFS: Number of write operations=2 S3: Number of bytes read=0 S3: Number of bytes written=0 S3: Number of read operations=0 S3: Number of large read operations=0 S3: Number of write operations=0 Job Counters Launched map tasks=1 Other local map tasks=1 Total time spent by all maps in occupied slots (ms)=149216 Total time spent by all reduces in occupied slots (ms)=0 Total time spent by all map tasks (ms)=4663 Total vcore-milliseconds taken by all map tasks=4663 Total megabyte-milliseconds taken by all map tasks=4774912 Map-Reduce Framework Map input records=1 Map output records=1 Input split bytes=137 Spilled Records=0 Failed Shuffles=0 Merged Map outputs=0 GC time elapsed (ms)=158 CPU time spent (ms)=4830 Physical memory (bytes) snapshot=522174464 Virtual memory (bytes) snapshot=4658302976 Total committed heap usage (bytes)=494927872 File Input Format Counters Bytes Read=299 File Output Format Counters Bytes Written=88 DistCp Counters Bytes Skipped=1048576000 Files Skipped=1 real 0m18.727s user 0m9.132s sys 0m0.356s [hadoop@ip-192-168-0-33 ~]$ s3-dist-cp [hadoop@ip-192-168-0-33 ~]$ time s3-dist-cp --src /user/hadoop/test3.txt --dest s3://<S3バケット>/ SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/usr/lib/hadoop/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/usr/share/aws/emr/emrfs/lib/slf4j-log4j12-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory] 22/02/03 07:08:42 INFO s3distcp.Main: Running with args: -libjars /usr/share/aws/emr/s3-dist-cp/lib/aopalliance-1.0.jar,/usr/share/aws/emr/s3-dist-cp/lib/guava-18.0.jar,/usr/share/aws/emr/s3-dist-cp/lib/guice-4.1.0.jar,/usr/share/aws/emr/s3-dist-cp/lib/guice-servlet-4.2.3.jar,/usr/share/aws/emr/s3-dist-cp/lib/javax.inject-1.jar,/usr/share/aws/emr/s3-dist-cp/lib/s3-dist-cp-2.18.0.jar,/usr/share/aws/emr/s3-dist-cp/lib/s3-dist-cp.jar --src /user/hadoop/test3.txt --dest s3://<S3バケット>/ 22/02/03 07:08:42 INFO s3distcp.S3DistCp: S3DistCp args: --src /user/hadoop/test3.txt --dest s3://<S3バケット>/ 22/02/03 07:08:42 INFO s3distcp.S3DistCp: Using output path 'hdfs:/tmp/883b2614-c0d0-47e2-b74b-f9ec51aeed17/output' 22/02/03 07:08:42 INFO s3distcp.S3DistCp: Try to recursively delete with throw Exceptionhdfs:/tmp/883b2614-c0d0-47e2-b74b-f9ec51aeed17/files 22/02/03 07:08:42 INFO s3distcp.S3DistCp: Try to recursively delete with throw Exceptionhdfs:/tmp/883b2614-c0d0-47e2-b74b-f9ec51aeed17/output 22/02/03 07:08:42 INFO s3distcp.S3ClientFactory: Create Amazon S3 client with endpoint override 22/02/03 07:08:43 INFO s3distcp.S3ClientFactory: DefaultAWSCredentialsProviderChain is used to create AmazonS3Client. 22/02/03 07:08:43 INFO s3distcp.FileInfoListing: Opening new file: hdfs:/tmp/883b2614-c0d0-47e2-b74b-f9ec51aeed17/files/1 22/02/03 07:08:43 INFO s3distcp.S3DistCp: Created 1 files to copy 1 files 22/02/03 07:08:45 INFO s3distcp.S3DistCp: Reducer number: 3 22/02/03 07:08:45 INFO client.RMProxy: Connecting to ResourceManager at ip-192-168-0-33.ap-northeast-1.compute.internal/192.168.0.33:8032 22/02/03 07:08:45 INFO client.AHSProxy: Connecting to Application History server at ip-192-168-0-33.ap-northeast-1.compute.internal/192.168.0.33:10200 22/02/03 07:08:46 INFO input.FileInputFormat: Total input files to process : 1 22/02/03 07:08:46 INFO mapreduce.JobSubmitter: number of splits:1 22/02/03 07:08:46 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1643867855502_0006 22/02/03 07:08:46 INFO conf.Configuration: resource-types.xml not found 22/02/03 07:08:46 INFO resource.ResourceUtils: Unable to find 'resource-types.xml'. 22/02/03 07:08:46 INFO resource.ResourceUtils: Adding resource type - name = memory-mb, units = Mi, type = COUNTABLE 22/02/03 07:08:46 INFO resource.ResourceUtils: Adding resource type - name = vcores, units = , type = COUNTABLE 22/02/03 07:08:46 INFO impl.YarnClientImpl: Submitted application application_1643867855502_0006 22/02/03 07:08:47 INFO mapreduce.Job: The url to track the job: http://ip-192-168-0-33.ap-northeast-1.compute.internal:20888/proxy/application_1643867855502_0006/ 22/02/03 07:08:47 INFO mapreduce.Job: Running job: job_1643867855502_0006 22/02/03 07:08:52 INFO mapreduce.Job: Job job_1643867855502_0006 running in uber mode : false 22/02/03 07:08:52 INFO mapreduce.Job: map 0% reduce 0% 22/02/03 07:08:57 INFO mapreduce.Job: map 100% reduce 0% 22/02/03 07:09:02 INFO mapreduce.Job: map 100% reduce 33% 22/02/03 07:09:03 INFO mapreduce.Job: map 100% reduce 67% 22/02/03 07:09:12 INFO mapreduce.Job: map 100% reduce 100% 22/02/03 07:09:12 INFO mapreduce.Job: Job job_1643867855502_0006 completed successfully 22/02/03 07:09:12 INFO mapreduce.Job: Counters: 54 File System Counters FILE: Number of bytes read=185 FILE: Number of bytes written=901493 FILE: Number of read operations=0 FILE: Number of large read operations=0 FILE: Number of write operations=0 HDFS: Number of bytes read=1048576423 HDFS: Number of bytes written=0 HDFS: Number of read operations=14 HDFS: Number of large read operations=0 HDFS: Number of write operations=6 S3: Number of bytes read=0 S3: Number of bytes written=1048576000 S3: Number of read operations=0 S3: Number of large read operations=0 S3: Number of write operations=0 Job Counters Launched map tasks=1 Launched reduce tasks=3 Data-local map tasks=1 Total time spent by all maps in occupied slots (ms)=244704 Total time spent by all reduces in occupied slots (ms)=3567168 Total time spent by all map tasks (ms)=2549 Total time spent by all reduce tasks (ms)=18579 Total vcore-milliseconds taken by all map tasks=2549 Total vcore-milliseconds taken by all reduce tasks=18579 Total megabyte-milliseconds taken by all map tasks=7830528 Total megabyte-milliseconds taken by all reduce tasks=114149376 Map-Reduce Framework Map input records=1 Map output records=1 Map output bytes=151 Map output materialized bytes=173 Input split bytes=173 Combine input records=0 Combine output records=0 Reduce input groups=1 Reduce shuffle bytes=173 Reduce input records=1 Reduce output records=0 Spilled Records=2 Shuffled Maps =3 Failed Shuffles=0 Merged Map outputs=3 GC time elapsed (ms)=579 CPU time spent (ms)=19600 Physical memory (bytes) snapshot=1606885376 Virtual memory (bytes) snapshot=26631655424 Total committed heap usage (bytes)=1451229184 Shuffle Errors BAD_ID=0 CONNECTION=0 IO_ERROR=0 WRONG_LENGTH=0 WRONG_MAP=0 WRONG_REDUCE=0 File Input Format Counters Bytes Read=250 File Output Format Counters Bytes Written=0 22/02/03 07:09:12 INFO s3distcp.S3DistCp: Try to recursively delete without throw Exceptionhdfs:/tmp/883b2614-c0d0-47e2-b74b-f9ec51aeed17 real 0m31.031s user 0m11.129s sys 0m0.432s [hadoop@ip-192-168-0-33 ~]$ s3-dist-cpやhadoop distcpはMapReduceを使用した分散処理のため、アプリケーション履歴として確認出来る。yarn上でメモリ確保して動くのでジョブ数については注意が必要。 --- ### AWSのグローバルリソースのデータの保存場所について date: 2022-02-20 url: https://zatoima.github.io/aws-global-resource-data/ tags: AWS 国内に情報は留めておきたいという要件があった場合において、グローバルリソースはどうなるのか?という点をメモ。 1.グローバルリソース グローバルリソースや例えばRoute53 、WAF 、CloudFront、IAM を指す。IAMはグローバルリソースで一つのリージョンに限らずにデータが複製される旨が記載がある。東京リージョンだけに留めたい場合においてもこのようなグローバル・サービスでは困難な場合がある。(とはいえ、保管される情報はログやメトリクスが主なのでその情報が海外リージョンに保管される場合、何が問題か?ということは整理する必要がある) https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/introduction.html IAM には、他の多くの AWS サービスと同様、結果整合性があります。IAM は、世界中の Amazon のデータセンター内の複数のサーバーにデータを複製することにより、高可用性を実現します。 グローバルリソース関連(エッジサービス含む) CloudTrailイベント CloudWatchメトリクス route53クエリログやWAFログ等 CloudFrontのSSL証明書 請求メトリクスデータ AWS Healthグローバルイベント 2.実は海外リージョンでしか使えない機能 リージョナルサービスだが、特定機能を使う場合には海外リージョンが使われてしまうパターン。これは他にも間違いなくある。 Cognito ユーザープールのイベントデータ CognitoのEメール設定リージョン SESの受信 マニュアルの抜粋箇所 随時見つけたら追記していきたいが、各サービスでバージニアリージョンだったり海外リージョンを経由してサービス提供が行われる機能をメモしていく。 サービス 分類 マニュアル抜粋 URL CloudWatch 請求メトリクスデータ 請求メトリクスデータは米国東部 (バージニア北部) リージョンに保存され、世界全体の請求額として表されます。このデータには、使用した AWS のサービス別の予想請求額と AWS 全体の予想請求額が含まれています。 https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/monitor_estimated_charges_with_cloudwatch.html CloudTrail CloudTrailイベント ほとんどのグローバルサービスの場合、イベントは米国東部 (バージニア北部) リージョンで発生しているものとしてログに記録されますが、一部のグローバルサービスイベントは米国東部 (オハイオ) リージョンや米国西部 (オレゴン) リージョンなどのその他のリージョンで発生しているものとしてログに記録されます。 https://docs.aws.amazon.com/ja_jp/awscloudtrail/latest/userguide/cloudtrail-concepts.html CloudFront CloudFront証明書 Amazon CloudFront で ACM 証明書を使用するには、米国東部 (バージニア北部) リージョン の証明書をリクエスト (またはインポート) していることを確認します。CloudFront ディストリビューションに関連づけられたこのリージョンの ACM 証明書は、このディストリビューションに設定されたすべての地域に分配されます。 https://docs.aws.amazon.com/ja_jp/acm/latest/userguide/acm-regions.html CloudFront CloudFront メトリクス CloudWatch API から CloudFront メトリクスを取得するには、米国東部 (バージニア北部) リージョン (us-east-1) を使用する必要があります。また、各メトリクスの特定の値とタイプも知っておく必要があります。 https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/programming-cloudwatch-metrics.html Route53 Route 53 メトリクス 現在のリージョンを米国東部 (バージニア北部) に変更します。それ以外のリージョンを現在のリージョンとして選択した場合、Route 53 のメトリクスは利用できません。 https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/monitoring-health-checks.html AWS Health AWS Healthグローバルイベント グローバルイベントを受信するには、米国東部 (バージニア北部) リージョンのルールを作成する必要があります。 https://docs.aws.amazon.com/ja_jp/health/latest/ug/cloudwatch-events-health.html Cognito E メール設定リージョン 使用する Amazon SES 設定リージョンを決定するときは、次のリージョンから選択する必要があります: us-east-1、us-west-2、または eu-west-1。 https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/user-pool-email.html Cognito Cognito ユーザープールのイベントデータ Amazon Cognito ユーザープールで Amazon Pinpoint 分析が使用される場合、イベントデータは米国東部 (バージニア北部) リージョンにルーティングされます。 https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/security-cognito-regional-data-considerations.html --- ### 更新が出来るデータレイクことレイクハウスとは date: 2022-02-13 url: https://zatoima.github.io/other-datalake-lakehouse-update/ tags: その他 ようやくデータレイクという言葉が自分の耳に馴染んできたところであるが、もう次のトレンドが出ているらしい。Parquet、ORC、Avroあたりが列志向フォーマットでデータレイクサービスでよく使われる"ファイルフォーマット"であるが、“テーブルフォーマット"としてApache Hudi、Delta Lake、Apache Icebergがあるらしい。AWSでは、Lake Formationで使用できるGoverned Tablesがこれにあたる。そのあたりをざっくりとメモ。 テーブルフォーマット 開発元 備考 Apache Hudi Uber Apacheに寄贈 Delta Lake Databricks Apache Iceberg Netflix Apacheに寄贈 Athenaで使用出来るIcebergしか触ったことはないが、実態としては、parquetファイルとメタデータファイルで構成されるものとなる。 イメージ図 赤枠のところが追加されたと理解している。テーブルを形成するためにどのように構造化されているかの間の抽象化レイヤー。ここが追加されることによってACIDの更新、削除、データバージョニングが出来る模様。 ※IcebargがORCに対応しているとかそういうのを表した図ではない。 例えば、AthenaからIcebargのテーブルを作った場合、次のようなファイルフォーマットとメタデータが生成される模様。 % aws s3 ls s3://xxxxx/iceberg_table/ --recursive 2021-12-06 21:30:30 0 iceberg_table/ 2021-12-07 13:42:38 453 iceberg_table/data/3494c159//iceberg_table/category=macbook/id_bucket=4/82f67f06-a0e1-4522-ba48-3cbe6d3a8be6.parquet 2021-12-07 13:45:35 438 iceberg_table/data/4b0be337//iceberg_table/category=macbook/id_bucket=4/dde0a679-84f8-46f4-891e-33355a25f396.parquet 2021-12-07 13:40:55 1417 iceberg_table/metadata/00000-60ff8e64-b2c6-4cc1-89b1-dc740816cf2d.metadata.json 2021-12-07 13:42:39 2336 iceberg_table/metadata/00001-b6262f06-8805-40c6-9b28-7b1d361f3705.metadata.json 2021-12-07 13:45:36 3289 iceberg_table/metadata/00002-79008873-1a1b-44db-830a-cdeae6c87dde.metadata.json 2021-12-07 13:42:38 7033 iceberg_table/metadata/958b8acb-2800-473b-b55e-486333344762-m0.avro 2021-12-07 13:45:35 7033 iceberg_table/metadata/b8518cfe-ffeb-4b58-880b-81ffe1156b85-m0.avro 2021-12-07 13:42:39 4270 iceberg_table/metadata/snap-1296825016097872104-1-958b8acb-2800-473b-b55e-486333344762.avro 2021-12-07 13:45:35 4340 iceberg_table/metadata/snap-6943776344382491461-1-b8518cfe-ffeb-4b58-880b-81ffe1156b85.avro 利点 データをテーブルとしてアクセスするために、ファイルのパスだけでなくデータのスキーマ、データの統計情報などもメタデータとして管理されている。下記のようなメリットがあるようだ。 データレイクのファイルをACIDで更新、削除ができる タイムトラベル(データバージョニング) スキーマの変更が容易 パフォーマンス icebergの公式ページでは次の通り説明されている。 https://iceberg.apache.org/ Schema evolution supports add, drop, update, or rename, and has no side-effects スキーマの進化は、追加、削除、更新、名前の変更に対応し、副作用はありません。 Hidden partitioning prevents user mistakes that cause silently incorrect results or extremely slow queries ヒドゥン・パーティショニングにより、ユーザーによるミスを防ぎ、無言の不正確な結果や極端に遅いクエリを防ぐことができます。 Partition layout evolution can update the layout of a table as data volume or query patterns change パーティションレイアウトの進化は、データ量やクエリーパターンの変化に応じて、テーブルのレイアウトを更新することができます。 Time travel enables reproducible queries that use exactly the same table snapshot, or lets users easily examine changes タイムトラベルにより、全く同じテーブルスナップショットを使用した再現性の高いクエリや、ユーザーが簡単に変更点を確認することができます。 Version rollback allows users to quickly correct problems by resetting tables to a good state バージョンロールバックにより、テーブルを良好な状態にリセットすることで、問題を迅速に修正することが可能 補足 Data Lakeの発展系としてこのLakehouseがどうなっていくのか見守りたい。AWSでもこのあたりが実装されてきたので今後どのように使われていくのかをしっかりとウォッチする。 参照先:https://www.integrate.io/jp/blog/meet-the-data-lakehouse-ja/#lakehouse 参考 Amazon Athena Apache IcebergテーブルフォーマットによるACID Transactionを試してみました! | DevelopersIO 更新できるデータレイクを作る 〜Apache Hudiを用いたユーザデータ基盤の刷新〜 - Gunosy Tech Blog AWS Lake Formation が、Governed Tables、ストレージの最適化、および行レベルのセキュリティをサポート AWS Lake Formation による効果的なデータレイクの構築 パート 1: governed tableを作成する | Amazon Web Services ブログ --- ### 技術面接対策用のナレッジ date: 2022-02-10 url: https://zatoima.github.io/other-technical-interview-preparation/ tags: その他, ブックマーク 海外のエンジニアの採用面接対策 system-design-primer/README-ja.md at master · donnemartin/system-design-primer · GitHub --- ### AWSの使用コストで割合が多い使用タイプをAWS CLIで出力する date: 2022-02-09 url: https://zatoima.github.io/aws-cost-exploler-aws-cli-usage-type/ tags: AWS これはCost Explolerのグループ化の条件で使用タイプを選択することで内訳を確認が出来る さっさと確認したい場合は、AWS CLIで下記を実行する aws ce get-cost-and-usage \ --time-period Start=2022-01-01,End=2022-01-30 \ --granularity MONTHLY \ --metrics UnblendedCost \ --group-by Type=DIMENSION,Key=USAGE_TYPE | jq -r '.ResultsByTime[].Groups[] | [(.Keys[]), .Metrics.UnblendedCost.Amount] | @csv' | awk -F\" '{print $2,$3,$4}' | sort -r -V -k 2 | head -n 20 実行結果 [ec2-user@bastin ~]$ aws ce get-cost-and-usage \ > --time-period Start=2022-01-01,End=2022-01-30 \ > --granularity MONTHLY \ > --metrics UnblendedCost \ > --group-by Type=DIMENSION,Key=USAGE_TYPE | jq -r '.ResultsByTime[].Groups[] | [(.Keys[]), .Metrics.UnblendedCost.Amount] | @csv' | awk -F\" '{print $2,$3,$4}' | sort -r -V -k 2 | head -n 20 APN1-NatGateway-Hours , 85.932 APN1-BoxUsage:m5.large , 85.932 APN1-Aurora:BackupUsage , 71.7980427228 APN1-EBS:VolumeUsage.gp3 , 61.2496773819 APN1-VpcEndpoint-Hours , 58.212 APN1-BoxUsage:t3.medium , 37.6992 APN1-LoadBalancerUsage , 33.6798 APN1-CW:Canary-runs , 28.0288 APN1-BoxUsage:t2.micro , 21.0672 APN1-Node:ra3.4xlarge , 18.342470776 APN1-BoxUsage:t3.large , 15.5833333696 APN1-EBS:VolumeUsage.gp2 , 14.5525795272 APN1-TimedStorage-ByteHrs , 12.0382298307 APN1-RDS:ChargedBackupUsage , 11.442173008 APN1-CW:MetricMonitorUsage , 7.2927419734 APN1-PaidEventsRecorded , 7.23436 USE1-IM-ResponsePlan-Months-Tier1 , 7 APN1-BackupUsage , 6.6523140684 ap-northeast-1-KMS-Keys , 5.580645072 APN1-PaidComplianceCheck , 5.619 --- ### AWS料金の「EC2 - Other」の料金をAWS CLIから確認する date: 2022-02-08 url: https://zatoima.github.io/aws-cost-exploler-ec2-other-cli/ tags: AWS やりたいこと AWSのコストで「EC2-Other」が高い場合があり、この内訳をAWS CLIベースでサクッと確認したい。 GUIベースでは? 「EC2-Other」の中で具体的に何に費用が掛かっているかについてはCost Explolerのフィルターでサービスとグループ化の条件で使用タイプを選択することで内訳を確認が出来る AWS CLIで実現する これをCLIで実現する際には下記のコマンドを実行する。各オプションの詳細はリファレンスを要確認。 get-cost-and-usage — AWS CLI 1.22.46 Command Reference フィルター用のファイルを作成する。今回はKeyとValuesにそれぞれ下記を設定 cat << EOF > ce_filter.json { "Dimensions": { "Key": "SERVICE", "Values": ["EC2 - Other"] } } EOF --filterに上記で作成したファイルを指定しつつ、 --group-byで使用タイプを設定する。後は高コストな使用タイプ順に出力する。ダブルクォーテーションで囲まれててうまくソート出来ていなかったので、awkでごにょごにょしている。 aws ce get-cost-and-usage \ --time-period Start=2022-01-01,End=2022-01-30 \ --granularity MONTHLY \ --metrics UnblendedCost \ --group-by Type=DIMENSION,Key=USAGE_TYPE \ --filter file://ce_filter.json | jq -r '.ResultsByTime[].Groups[] | [(.Keys[]), .Metrics.UnblendedCost.Amount] | @csv' | awk -F\" '{print $2,$3,$4}' | sort -r -k 2 | head -n 10 実行結果 [ec2-user@bastin ~]$ aws ce get-cost-and-usage \ > --time-period Start=2022-01-01,End=2022-01-30 \ > --granularity MONTHLY \ > --metrics UnblendedCost \ > --group-by Type=DIMENSION,Key=USAGE_TYPE \ > --filter file://ce_filter.json | jq -r '.ResultsByTime[].Groups[] | [(.Keys[]), .Metrics.UnblendedCost.Amount] | @csv' | awk -F\" '{print $2,$3,$4}' | sort -r -k 2 | head -n 10 APN1-NatGateway-Hours , 85.932 APN1-EBS:VolumeUsage.gp3 , 61.2496773819 APN1-EBS:VolumeUsage.gp2 , 14.5525795272 APN1-NatGateway-Bytes , 0.1139805019 APN1-USE1-AWS-Out-Bytes , 0.000031066 APN1-USW2-AWS-Out-Bytes , 0.0000110895 APN1-APS1-AWS-Out-Bytes , 0.0000010102 APN1-USW1-AWS-Out-Bytes , 0.0000002506 APN1-APS3-AWS-Out-Bytes , 0.0000001677 APN1-APN2-AWS-Out-Bytes , 0.0000001634 [ec2-user@bastin ~]$ --- ### お名前.comで取得したドメインを使用してACMでSSL証明書を発行する date: 2022-02-07 url: https://zatoima.github.io/aws-acm-ssl-certigication-setting/ tags: AWS, ACM 表題の通り、お名前.comで取得したドメインを使用してACMでSSL証明書を発行する際のメモ。 ACMからパブリック証明書をリクエスト ドメイン名と検証方法を入力 証明書の発行中。しばらく待機する 証明書の詳細画面に移動して、「CSVにエクスポート」を選択して手元にダウンロードしておく。後続の手順で参照。 お名前.comに移動して「DNSレコードを設定する」に移動 対象ドメインを選択して次へ DNSレコード設定を利用する ACMの画面から下記のようなCSVをダウンロードしているはずなのでここから下記を入力する ホスト名 TYPE VALUE Domain Name CNAME Record Value 入力して追加する ページ下部の設定はデフォルトのままチェックを付ける 設定するをクリック 完了となる 数時間から24時間程度と書かれているのでDNSの伝搬に時間が掛かるので気長に待つ。 https://help.onamae.com/answer/8081 数十分でステータスが発行済に変更になった 参考 検証を保留中の ACM 証明書の解決 https://aws.amazon.com/jp/premiumsupport/knowledge-center/acm-certificate-pending-validation/ --- ### Spark on Docker on EC2環境を構築する date: 2022-02-04 url: https://zatoima.github.io/aws-ec2-on-docker-on-spark-install/ tags: Docker, Spark, AWS 私がSpark環境を使用する際にはAWSのEMRが基本となるが、EC2のxlargeを最低3台は必要で、かつ作成までに10分弱くらいは掛かってしまうので簡単にPySparkのスクリプトを試したい時用のSpark on Docker on EC2環境を作成。 Dockerのバージョン [ec2-user@bastin ~]$ docker -v Docker version 20.10.7, build f0df350 pyspark-notebookのコンテナをpullする [ec2-user@bastin ~]$ docker pull jupyter/pyspark-notebook Using default tag: latest latest: Pulling from jupyter/pyspark-notebook ea362f368469: Pull complete 1c2cc406fa63: Pull complete 669dbb3f6366: Pull complete 3923fd8d3607: Pull complete d5da8a60f05b: Pull complete 78722f61450a: Pull complete 92fcb4043b45: Pull complete e43cca32fa72: Pull complete d6e059957f76: Pull complete d4c1ac4b2556: Pull complete 662cec5dfc0c: Pull complete 2c1cefff5d33: Pull complete 759c927f13aa: Pull complete 804a283b4e2b: Pull complete a702bc58bb3e: Pull complete 3da5ff2c18c0: Pull complete 31672a0ad050: Pull complete 105e72cf5bd3: Pull complete 1124e4036913: Pull complete e9c2829123b2: Pull complete 57daad9176a1: Pull complete e6caa5647846: Pull complete d6b9c536082e: Pull complete f6e352309aa2: Pull complete Digest: sha256:398bab89543dc94d75a24869665c1433e10645bd100267a6f89e8768477d14a8 Status: Downloaded newer image for jupyter/pyspark-notebook:latest docker.io/jupyter/pyspark-notebook:latest pyspark-notebookのコンテナを実行 [ec2-user@bastin ~]$ docker run -p 8888:8888 -e JUPYTER_ENABLE_LAB=yes --name pyspark jupyter/pyspark-notebook WARNING: JUPYTER_ENABLE_LAB is ignored, use DOCKER_STACKS_JUPYTER_CMD if you want to change the command used to start the server Entered start.sh with args: jupyter lab /usr/local/bin/start.sh: running hooks in /usr/local/bin/before-notebook.d as uid / gid: 1000 / 100 /usr/local/bin/start.sh: running script /usr/local/bin/before-notebook.d/spark-config.sh /usr/local/bin/start.sh: done running hooks in /usr/local/bin/before-notebook.d Executing the command: jupyter lab [I 2022-01-28 13:50:43.462 ServerApp] jupyterlab | extension was successfully linked. [W 2022-01-28 13:50:43.467 NotebookApp] 'ip' has moved from NotebookApp to ServerApp. This config will be passed to ServerApp. Be sure to update your config before our next release. [W 2022-01-28 13:50:43.468 NotebookApp] 'port' has moved from NotebookApp to ServerApp. This config will be passed to ServerApp. Be sure to update your config before our next release. [W 2022-01-28 13:50:43.468 NotebookApp] 'port' has moved from NotebookApp to ServerApp. This config will be passed to ServerApp. Be sure to update your config before our next release. [I 2022-01-28 13:50:43.475 ServerApp] Writing Jupyter server cookie secret to /home/jovyan/.local/share/jupyter/runtime/jupyter_cookie_secret [I 2022-01-28 13:50:43.864 ServerApp] nbclassic | extension was successfully linked. [I 2022-01-28 13:50:43.901 ServerApp] nbclassic | extension was successfully loaded. [I 2022-01-28 13:50:43.903 LabApp] JupyterLab extension loaded from /opt/conda/lib/python3.9/site-packages/jupyterlab [I 2022-01-28 13:50:43.903 LabApp] JupyterLab application directory is /opt/conda/share/jupyter/lab [I 2022-01-28 13:50:43.906 ServerApp] jupyterlab | extension was successfully loaded. [I 2022-01-28 13:50:43.907 ServerApp] Serving notebooks from local directory: /home/jovyan [I 2022-01-28 13:50:43.907 ServerApp] Jupyter Server 1.13.4 is running at: [I 2022-01-28 13:50:43.907 ServerApp] http://eff596c2a2b0:8888/lab?token=65c095c6ac9d7bf2d3eec7189bc1c0e8e5c254f1aad33689 [I 2022-01-28 13:50:43.907 ServerApp] or http://127.0.0.1:8888/lab?token=65c095c6ac9d7bf2d3eec7189bc1c0e8e5c254f1aad33689 [I 2022-01-28 13:50:43.907 ServerApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation). [C 2022-01-28 13:50:43.910 ServerApp] To access the server, open this file in a browser: file:///home/jovyan/.local/share/jupyter/runtime/jpserver-7-open.html Or copy and paste one of these URLs: http://eff596c2a2b0:8888/lab?token=65c095c6ac9d7bf2d3eec7189bc1c0e8e5c254f1aad33689 or http://127.0.0.1:8888/lab?token=65c095c6ac9d7bf2d3eec7189bc1c0e8e5c254f1aad33689 [I 2022-01-28 13:51:18.309 LabApp] Build is up to date jupyterのコンソールに移動 Public IPやElastic IPを付与している場合。セキュリティグループ等で許可を。 http://<Public IP>:8888/lab?token=65c095c6ac9d7bf2d3eec7189bc1c0e8e5c254f1aad33689 OtherにあるTerminalをクリックするとPySpark環境を実行出来るようになる --- ### Redshift Spectrumの同時実行性能パフォーマンス date: 2022-01-29 url: https://zatoima.github.io/aws-redshift-spectrum-performance-concurrency/ tags: AWS, Redshift Redshift Spectrumの同時実行性能がどのように決まるのかをメモ。 1.スライス数 この要素自体はSpectrumに限らず通常のRedshiftでも重要な概念となる。 スライス数は1つ目の要素としてインスタンスタイプ(インスタンスサイズ)によって決まる。各スライスは、ノードのメモリとディスク容量の一部を割り当てられ、ノードに割り当てられたワークロードの一部分を処理する。リーダーノードは、スライスへのデータの分散を管理し、クエリまたは他のデータベース操作のワークロードをスライスに分配して、各スライスはそれぞれがワークロードを担当する。下記のように各ノードには複数のスライスが存在する。 参照元:データウェアハウスシステムのアーキテクチャ - Amazon Redshift このスライス数はノードごとのデフォルトスライスとしてノードサイズによって事前に決まっている。 Amazon Redshift クラスター - Amazon Redshift - ノードタイプの詳細 RA3の場合、ra3.xlplusは「2」、ra3.4xllargeは「4」、ra3.16xlageは「16」となる。 ノードサイズのサイズ変更の仕方によってスライス数が変更されないこともあるのでオペレーション時には注意した方が良いというハマリポイントがある。 [Amazon Redshift クラスター - Amazon Redshift - ノードタイプの詳細](Amazon Redshift クラスター - Amazon Redshift) ノードあたりのスライスの数は、従来のサイズ変更でクラスターを作成またはサイズ変更するときに、コンピューティングノードがパーティション分割されるデフォルトのスライス数です。 伸縮自在なリサイズを使用してクラスターのサイズを変更すると、ノードあたりのスライス数が変わる可能性があります。 ただし、クラスターのすべてのコンピューティングノードのスライスの総数は、伸縮自在なサイズ変更後も変わりません。 スナップショットからの復元操作を使用してクラスターを作成する場合、ノードタイプを変更すると、元のクラスターから生成されるクラスターのスライスの数が変わることがあります。 2.同時実行数 1クエリ 1 スライスにつき最大 10 の同時実行数となっている。 いくつのクエリが同時に実行されているかによって、同時実行数が変わる 割りあてられた同時実行数によって、S3 をスキャンするスレッド数が制限される ※「最大」となっているのもおそらく注意点であるし、かつ確認する限りマニュアルにもSpectrum層-S3の同時実行数の記載がないところにも注意。ユーザ側には意識させないところだとは思われるが、明確には仕様が示されていない。 参照先:Amazon Redshift Spectrum 12 のベストプラクティス | Amazon Web Services ブログ Spectrumのパフォーマンスについて 「1.スライス数」と「2.同時実行数」の話をまとめるとこのようになると考えられる。 Spectrumの同時実行の確認方法について SVL_S3QUERY_SUMMARY表を確認。スライスで処理するファイル数や並列リクエストなどの統計もあるのでここで確認する SVL_S3QUERY_SUMMARY - Amazon Redshift 列名 説明 files この Redshift Spectrum クエリで処理されたファイル数。ファイル数が少ないと、並列処理の利点は制限されます。 files_max 1 つのスライスで処理されるファイルの最大数。 files_avg 1 つのスライスで処理されるファイルの平均数。 splits このセグメントで処理された分割の数。このスライスで処理された分割の数。例えば分割可能なデータファイルの容量が大きい場合 (約 512 MB を超えるデータファイルなど)、Redshift Spectrum はファイルを複数の S3 リクエストに分割し、並列処理を試みます。 splits_max このスライスで処理された分割の最大数。 splits_avg このスライスで処理された分割の平均数。 total_split_size 処理されたすべての分割の合計サイズ。 max_split_size 処理された分割の最大サイズ (単位: バイト)。 avg_split_size 処理された分割の平均サイズ (単位: バイト)。 total_retries 個別の処理ファイルでの再試行の総数。 max_retries 処理ファイルでの再試行の最大数。 max_request_duration 個別ファイルリクエストの最長時間 (マイクロ秒)。実行時間の長いクエリはボトルネックの可能性があります。 avg_request_duration ファイルリクエストの平均時間 (マイクロ秒)。 max_request_parallelism Redshift Spectrum クエリでの 1 つのスライスの並列リクエストの最大数。 avg_request_parallelism Redshift Spectrum クエリでの 1 つのスライスの並列リクエストの平均数。 Spectrumの同時実行性能のパフォーマンスを最大化するためには? ここにある通りS3側にある分割されたファイル数と同時実行数が最適なバランスになっているかを確認する必要がある。 ・Amazon Redshift Spectrum 12 のベストプラクティス | Amazon Web Services ブログ ファイル総数 <= クエリごとの同時実行性能 (例えば 10) * クラスターのスライス数、といった簡単な計算ができます。。ただしクラスターのノード数を増やしても、必ずしもパフォーマンスが向上するとは限りません。最適なクラスターのノード数は、以下のようにして決めてください。まず Redshift Spectrum の外部テーブルに、いくつのファイルが含まれているかを確認してください。続いてクラスターのサイズを大きくしていって(クラスターに含まれるスライス数を増やすということです)、ノード数が増えてもパフォーマンスがこれ以上伸びなくなるというポイントを探してください。そのときのノードタイプにおける、最適な Redshift のクラスターサイズは、それ以上のパフォーマンス向上が起こらなくなるところです。 力技であればRedshiftのクラスタを複数台並べてクエリを掛けることで更に並列度自体は挙げられる。ストレージとコンピュートが分離されているSpectrumの利点の一つだと思う。クラスタを複数を立ててそれぞれのクラスタから同じS3のファイルにクエリすることも出来る。 補足:Redshift SpectrumのConcurrency Scaling Redshift Spectrum自体もConcurrency Scalingは対象の模様。以前はSpectrumのConcurrency Scalingは対象外だった模様。マニュアルは少々分かりづらい記載になっているが、Forumの方では記載があった。(※実際には試していない) 同時実行スケーリングを使用する - Amazon Redshift 制限のあるネットワークまたは仮想プライベートクラウド (VPC) 構成で保護されている、外部リソースにアクセスするクエリはサポートされません。 AWS Developer Forums: Amazon Redshift Announcements ... Redshift Spectrum: UNLOAD and queries that use Spectrum to reference external tables are now eligible for Concurrency Scaling 参考 Amazon Redshift Spectrum 12 のベストプラクティス | Amazon Web Services ブログ Amazon Redshift で伸縮自在なサイズ変更を使用する --- ### Redshiftから特定区切り文字でファイル出力する date: 2022-01-27 url: https://zatoima.github.io/aws-redshift-system-table-unload/ tags: AWS, Redshift 検証時にRedshiftのシステムテーブルなどのデータを抜いて退避させたい。 ヘッダー出力ONで、デフォルトだとスライス数分ファイルが分割して、マージするのも面倒なためパラレルをオフにして「|」区切りにしてgzip形式で出力するコマンド。ファイル重複する場合、上書きする。 unload ('select * from svl_s3query_summary order by elapsed;') to 's3://ssbgz-spectrum/svl_s3query_summary_log' iam_role 'arn:aws:iam::xxxxxxxxxxxx:role/myRedshiftRole' delimiter '|' header format csv gzip parallel off allowoverwrite; 区切り文字付きまたは固定幅形式でデータをアンロードする - Amazon Redshift https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/t_unloading_fixed_width_data.html --- ### Apache Bench(abコマンド)で簡易的なアクセスをCloudFrontに実行 date: 2022-01-24 url: https://zatoima.github.io/aws-cloudfront-apache-bench-ab-access/ tags: AWS, CloudFront Apacheをインストール [ec2-user@bastin ~]$ sudo yum -y install apache Loaded plugins: langpacks, priorities, update-motd amzn2-core ~省略~ 6/6 Installed: httpd.x86_64 0:2.4.51-1.amzn2 Dependency Installed: generic-logos-httpd.noarch 0:18.0.0-4.amzn2 httpd-filesystem.noarch 0:2.4.51-1.amzn2 httpd-tools.x86_64 0:2.4.51-1.amzn2 mailcap.noarch 0:2.1.41-2.amzn2 mod_http2.x86_64 0:1.15.19-1.amzn2.0.1 Complete! abコマンドのオプション よく使うのは-n、-cあたりか。 [ec2-user@bastin ~]$ ab ab: wrong number of arguments Usage: ab [options] [http[s]://]hostname[:port]/path Options are: -n requests Number of requests to perform -c concurrency Number of multiple requests to make at a time -t timelimit Seconds to max. to spend on benchmarking This implies -n 50000 -s timeout Seconds to max. wait for each response Default is 30 seconds -b windowsize Size of TCP send/receive buffer, in bytes -B address Address to bind to when making outgoing connections -p postfile File containing data to POST. Remember also to set -T -u putfile File containing data to PUT. Remember also to set -T -T content-type Content-type header to use for POST/PUT data, eg. 'application/x-www-form-urlencoded' Default is 'text/plain' -v verbosity How much troubleshooting info to print -w Print out results in HTML tables -i Use HEAD instead of GET -x attributes String to insert as table attributes -y attributes String to insert as tr attributes -z attributes String to insert as td or th attributes -C attribute Add cookie, eg. 'Apache=1234'. (repeatable) -H attribute Add Arbitrary header line, eg. 'Accept-Encoding: gzip' Inserted after all normal header lines. (repeatable) -A attribute Add Basic WWW Authentication, the attributes are a colon separated username and password. -P attribute Add Basic Proxy Authentication, the attributes are a colon separated username and password. -X proxy:port Proxyserver and port number to use -V Print version number and exit -k Use HTTP KeepAlive feature -d Do not show percentiles served table. -S Do not show confidence estimators and warnings. -q Do not show progress when doing more than 150 requests -l Accept variable document length (use this for dynamic pages) -g filename Output collected data to gnuplot format file. -e filename Output CSV file with percentages served -r Don't exit on socket receive errors. -m method Method name -h Display usage information (this message) -I Disable TLS Server Name Indication (SNI) extension -Z ciphersuite Specify SSL/TLS cipher suite (See openssl ciphers) -f protocol Specify SSL/TLS protocol (SSL3, TLS1, TLS1.1, TLS1.2 or ALL) -E certfile Specify optional client certificate chain and private key CloudFrontのディストリビューションに簡易的なアクセスを実施 [ec2-user@bastin ~]$ ab -n 10000 -c 10 https://d35onj12it5a8t.cloudfront.net/date.html This is ApacheBench, Version 2.3 <$Revision: 1879490 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking d35onj12it5a8t.cloudfront.net (be patient) Completed 1000 requests Completed 2000 requests Completed 3000 requests Completed 4000 requests Completed 5000 requests Completed 6000 requests Completed 7000 requests Completed 8000 requests Completed 9000 requests Completed 10000 requests Finished 10000 requests Server Software: AmazonS3 Server Hostname: d35onj12it5a8t.cloudfront.net Server Port: 443 SSL/TLS Protocol: TLSv1.2,ECDHE-RSA-AES128-GCM-SHA256,2048,128 Server Temp Key: ECDH P-256 256 bits TLS Server Name: d35onj12it5a8t.cloudfront.net Document Path: /date.html Document Length: 469 bytes Concurrency Level: 10 Time taken for tests: 12.832 seconds Complete requests: 10000 Failed requests: 0 Total transferred: 9240000 bytes HTML transferred: 4690000 bytes Requests per second: 779.33 [#/sec] (mean) Time per request: 12.832 [ms] (mean) Time per request: 1.283 [ms] (mean, across all concurrent requests) Transfer rate: 703.22 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 5 10 2.8 10 67 Processing: 1 3 1.0 3 10 Waiting: 1 3 1.0 3 10 Total: 6 13 3.7 13 72 Percentage of the requests served within a certain time (ms) 50% 13 66% 13 75% 16 80% 17 90% 18 95% 18 98% 19 99% 20 100% 72 (longest request) 結果から主に見るポイント No. 項目 説明 結果サンプル 1 Concurrency Level 同時実行数 10 2 Time taken for tests テスト時間 12.832 seconds 3 Complete requests 総リクエスト数 10000 4 Failed requests 失敗したリクエスト 0 5 Total transferred 転送量(全体) 9240000 bytes 6 HTML transferred 転送量(HTML) 4690000 bytes 7 Requests per second 1秒間あたりのリクエスト数 779.33 [#/sec] (mean) 8 Transfer rate 転送レート 703.22 [Kbytes/sec] received 参考 Apache Benchでサクッと性能テスト - Qiita https://qiita.com/flexfirm/items/ac5a2f53cfa933a37192 Apache Benchの結果の見方 - Qiita https://qiita.com/nnmr/items/2be82691e19da261c4e4 --- ### PostgreSQLでソートをメモリでは無く敢えてディスクで発生させる方法 date: 2022-01-20 url: https://zatoima.github.io/postgres-disk-external-merge-sort/ tags: PostgreSQL pgbenchでデータ生成 適宜スケールファクターの数値を設定する create database pgbench; pgbench -i -s 100 -U postgres -h aurorapgsqlv1.cluster-xxx.ap-northeast-1.rds.amazonaws.com work_memを低い数値に設定してSQLを実行 SET work_mem=1024; EXPLAIN (ANALYZE,BUFFERS) SELECT t1.aid,t1.bid,t1.abalance,t2.bbalance FROM pgbench_accounts t1, pgbench_branches t2 where t1.bid=t2.bid ORDER BY t1.abalance DESC; 実行ログ external merge Diskが発生していて147秒もかかっている。大部分がSort部分。 pgbench=> SET work_mem=1024; SET pgbench=> pgbench=> EXPLAIN (ANALYZE,BUFFERS) SELECT t1.aid,t1.bid,t1.abalance,t2.bbalance FROM pgbench_accounts t1, pgbench_branches t2 where t1.bid=t2.bid ORDER BY t1.abalance DESC; QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------- Gather Merge (cost=11000684.94..20723586.06 rows=83333334 width=16) (actual time=110248.334..141130.354 rows=100000000 loops=1) Workers Planned: 2 Workers Launched: 2 Buffers: shared hit=1639508, temp read=1828307 written=1835749 -> Sort (cost=10999684.91..11103851.58 rows=41666667 width=16) (actual time=109509.807..113561.825 rows=33333333 loops=3) Sort Key: t1.abalance DESC Sort Method: external merge Disk: 852192kB Worker 0: Sort Method: external merge Disk: 855776kB Worker 1: Sort Method: external merge Disk: 836160kB Buffers: shared hit=1639508, temp read=1828307 written=1835749 -> Hash Join (cost=27.50..2165877.71 rows=41666667 width=16) (actual time=0.328..10296.741 rows=33333333 loops=3) Hash Cond: (t1.bid = t2.bid) Buffers: shared hit=1639414 -> Parallel Seq Scan on pgbench_accounts t1 (cost=0.00..2056011.67 rows=41666667 width=12) (actual time=0.004..4573.584 rows=33333333 loops=3) Buffers: shared hit=1639345 -> Hash (cost=15.00..15.00 rows=1000 width=8) (actual time=0.272..0.273 rows=1000 loops=3) Buckets: 1024 Batches: 1 Memory Usage: 48kB Buffers: shared hit=15 -> Seq Scan on pgbench_branches t2 (cost=0.00..15.00 rows=1000 width=8) (actual time=0.005..0.107 rows=1000 loops=3) Buffers: shared hit=15 Planning Time: 0.386 ms Execution Time: 147284.085 ms (22 rows) --- ### OracleとPostgreSQLの統計情報取得のサンプリング数の違いについて date: 2022-01-17 url: https://zatoima.github.io/oracle-postgresql-dbms-stats-analyze-sampling/ tags: Oracle, PostgreSQL 統計情報取得というのはDBエンジンに関係なく、オプティマイザ(プランナ)の適切な実行計画生成のためには必要不可欠な仕組みであるが、サンプリング数と精度はトレードオフの関係にある。サンプリング数が多いと統計情報取得に掛かる時間が長くなってしまうし、データの母数に対してサンプルが少ないと統計情報の精度が落ち、結果として最適な実行計画が生成されないかもしれない。 OracleとPostgreSQLの統計情報取得を比較してみたところ圧倒的にPostgreSQLの統計情報の取得時間が短かったので、その理由について簡単にメモしておく。結論として両者デフォルトの場合、PostgreSQLの方はある程度サンプリング数は固定化されているのに対してOracleの場合はAUTO_SAMPLE_SIZEでテーブルサイズによってサンプリング数が増減する。この違いによって取得時間も大きく変わってきているようだ。(あくまで原因の一つ。) Oracleの場合 DBMS_STATSパッケージのESTIMATE_PERCENTパラメータで指定する。デフォルトはAUTO_SAMPLE_SIZEで自動でOracle側が最適なサンプリング数を算出してくれる。大きなテーブルはサンプリング数が多くなり、小さいテーブルはサンプリング数が小さくなる。“100%のサンプリングの精度”、“10%サンプリングの所要時間"を両立とあるので素晴らしい機能だと思う。統計的にもそれだけ取れば精度として十分なんだろう。 PL/SQLパッケージおよびタイプ・リファレンス https://docs.oracle.com/cd/F19136_01/arpls/DBMS_STATS.html#GUID-7D7442B5-B060-40E9-AA18-2085E527C3B1 サンプリングする行のパーセントが決定されます。 有効範囲は0.000001から100です。定数DBMS_STATS.AUTO_SAMPLE_SIZEを使用すると、最適な統計を生成するための適切なサンプル・サイズをデータベースで決定できるようになります。これはデフォルトです。 Oracle Database 19cにおけるオプティマイザ統計収集のベスト・プラクティス https://www.oracle.com/technetwork/jp/database/bi-datawarehousing/twp-bp-for-stats-gather-19c-5324205-ja.pdf ESTIMATE_PERCENTパラメータは、統計を計算するために使用される行の割合を決定します。もっとも正確な統計は、表のすべての行が処理される(つまりサンプルが100 %の)ときに収集され、通常は算出された統計と呼ばれます。Oracle Database 11gでは、確定的な統計を実現するハッシュ・ベースの新しいサンプリング・アルゴリズムが導入されました。この新たなアプローチでは、最大 で10 %のサンプルのコストで、100 %のサンプルに近い正確性を実現します。 PostgreSQLの場合 サンプリング量はデフォルト 30,000 レコード( MAX(列の STATISTICS 値)× 300 レコード) STATISTICS 値は下記で決まる。 default_statistics_targetパラメーター(デフォルト:100) テーブルの各カラムに対して実施するALTER TABLEコマンドのSET STATISTICS文 式として定義されたインデックス列に対するALTER INDEXコマンドのSET STATISTICS文 大きめのテーブルに対してanalyzeコマンドにオプションverboseを付与して実行してみる。30000 rows in sampleやscanned 30000 of 163935 pagesとある。 postgres=> show default_statistics_target; default_statistics_target --------------------------- 100 (1 row) postgres=> select count(*) from pgbench_accounts; count ---------- 10000000 (1 row) postgres=> postgres=> analyze verbose pgbench_accounts; INFO: analyzing "public.pgbench_accounts" INFO: "pgbench_accounts": scanned 30000 of 163935 pages, containing 1830000 live rows and 0 dead rows; 30000 rows in sample, 10000035 estimated total rows ANALYZE postgres=> postgres=> select count(*) from pgbench_branches; count ------- 100 (1 row) postgres=> analyze verbose pgbench_branches; INFO: analyzing "public.pgbench_branches" INFO: "pgbench_branches": scanned 1 of 1 pages, containing 100 live rows and 0 dead rows; 100 rows in sample, 100 estimated total rows ANALYZE 数億行等で列値にバリエーションが多い場合はこのサンプル数では適切な実行計画が導き出されない可能性がもちろんある。こういう場合はdefault_statistics_targetパラメーター等(特定列のみサンプリング数を多くすることも出来るので詳細にチューニングしたい場合はそちらの方が良いかもしれない)を調整してサンプリング数を多くする必要がある。当然サンプリング数を多くすると時間が掛かってしまうのでトレードオフに注意すること。 マニュアルの該当箇所はこちら。 ANALYZE https://www.postgresql.jp/document/13/html/sql-analyze.html 巨大なテーブルでは、ANALYZEは、全ての行を検査するのではなく、テーブルの中からランダムにサンプルを取り出して使用します。 これによって、非常に巨大なテーブルであっても短時間で解析することが可能です。 しかし、このようにして得られた統計情報はおおよそのものでしかなく、テーブルの内容に変更がなくてもANALYZEを実行する度に変化することに注意してください。 これにより、EXPLAINが表示する、プランナの推定コストも多少変化する可能性があります。 稀に、このような不確定要素のせいで、プランナがANALYZEを実行した後に異なる問い合わせ計画を選択してしまうことがあります。 これを防止するには、以下に示すようにANALYZEで収集される統計情報の量を増やしてください。 設定パラメータ変数default_statistics_targetを調整するか、もしくはALTER TABLE ... ALTER COLUMN ... SET STATISTICS(ALTER TABLE参照)を使用して列単位の統計目標を列毎に設定することで、解析の範囲を制御することができます。 目標値として設定するのは、典型的な値のリストにおけるエントリ数の最大値と度数分布のビンの最大数です。 デフォルトの目標値は100です。 しかし、この値は、プランナの推定精度とANALYZEの処理時間、pg_statisticの占める容量とのトレードオフによって大きくも小さくも調整されることがあります。 目標値を0に設定すると、その列に関する統計情報の収集は無効になります。 決してWHERE句、GROUP BY句、ORDER BY句に使用されない列に対しては、このような設定が有用です。 プランナにとってそのような列の統計情報は不要だからです。 参考 Best Practices for Gathering Optimizer Statistics with Oracle Database 19c https://www.oracle.com/technetwork/jp/database/bi-datawarehousing/twp-bp-for-stats-gather-19c-5324205-ja.pdf?utm_source=pocket_mylist Oracle Statistics Concepts https://www.oracle.com/technetwork/jp/database/bi-datawarehousing/twp-stats-concepts-19c-5324209-ja.pdf?utm_source=pocket_mylist 書籍:内部構造から学ぶPostgreSQL 設計・運用計画の鉄則 --- ### Fiware/Orionで使うMongoDBへの接続先を変更する date: 2022-01-15 url: https://zatoima.github.io/fireware-orion-mongodb-connection-change/ tags: Docker, Fiware マニュアルの参照先はここになる。Firewareの公式マニュアルがGoogleで引っかかりにくいのは何故。 Docker - FIWARE-Orion https://fiware-orion.letsfiware.jp/user/docker/ 2A. MongoDB はローカルホスト上にある場合 これを実行するには、このコマンドを実行します。 sudo docker run -d --name orion1 -p 1026:1026 fiware/orion すべてが動作することを確認します。 curl localhost:1026/version 2B. MongoDB が別の Docker コンテナで動作している場合 他のコンテナで MongoDB を実行したい場合は、次のように起動することができます sudo docker run --name mongodb -d mongo:4.4 そして、このコマンドで Orion を実行します sudo docker run -d --name orion1 --link mongodb:mongodb -p 1026:1026 fiware/orion -dbhost mongodb すべてが動作することを確認します。 curl localhost:1026/version このメソッドは、セクション1で説明したものと機能的に同等ですが、docker-compose ファイルではなく手動でステップを実行します。 MongoDB コンテナを無効にするとすぐにデータが失われます。 2C. MongoDB が異なるホスト上で動作している場合 別の MongoDB インスタンスに接続する場合は、前のコマンドの代わりに、次のコマンドを実行します sudo docker run -d --name orion1 -p 1026:1026 fiware/orion -dbhost <MongoDB Host> すべてが動作することを確認します。 curl localhost:1026/version --- ### S3オブジェクトの整合性チェックをどのように行うのか date: 2022-01-11 url: https://zatoima.github.io/aws-s3-object-checksum-how-to/ tags: AWS, S3 下記の記事でも書いた通り、S3へマルチアップロードを行った際はMD5とEtagに差異が発生する。 S3オブジェクトのmd5やEtagの関係性について整理する | my opinion is my own https://zatoima.github.io/aws-s3-object-md5-etag/ アップロード時 下記記載の通り、AWS CLIで実行される。標準アップロードとマルチパートアップロードの両方でチェックサム検証を行うと記載ある https://docs.aws.amazon.com/cli/latest/topic/s3-faq.html Q: Does the AWS CLI validate checksums? The AWS CLI will perform checksum validation for uploading and downloading files in specific scenarios. Upload The AWS CLI will calculate and auto-populate the Content-MD5 header for both standard and multipart uploads. If the checksum that S3 calculates does not match the Content-MD5 provided, S3 will not store the object and instead will return an error message back the AWS CLI. The AWS CLI will retry this error up to 5 times before giving up. On the case that any files fail to transfer successfully to S3, the AWS CLI will exit with a non zero RC. See aws help return-codes for more information. Q: AWS CLI はチェックサムの検証を行いますか? AWS CLIは、特定のシナリオでファイルのアップロードとダウンロードのチェックサム検証を実行します。 アップロード AWS CLI は、標準アップロードとマルチパートアップロードの両方で Content-MD5 ヘッダを計算し、自動入力することができます。S3が計算したチェックサムが提供されたContent-MD5と一致しない場合、S3はオブジェクトを保存せず、代わりにAWS CLIにエラーメッセージを返します。AWS CLIはこのエラーを5回までリトライして、あきらめる。S3へのファイル転送に失敗した場合、AWS CLIは0以外のRCで終了します。詳細はaws help return-codesを参照してください。 ダウンロード時 下記の通り、特定条件で整合性チェックが出来ない旨、記載があるので注意が必要。 オブジェクトがマルチパートアップロードでアップロードされた場合 オブジェクトがKMSによるサーバーサイドの暗号化を使用してアップロードされた場合 顧客が提供した暗号化キーを使用してオブジェクトをアップロードした場合 Download The AWS CLI will attempt to verify the checksum of downloads when possible, based on the ETag header returned from a GetObject request that’s performed whenever the AWS CLI downloads objects from S3. If the calculated MD5 checksum does not match the expected checksum, the file is deleted and the download is retried. This process is retried up to 3 times. If a downloads fails, the AWS CLI will exit with a non zero RC. See aws help return-codes for more information. There are several conditions where the CLI is not able to verify checksums on downloads: If the object was uploaded via multipart uploads If the object was uploaded using server side encryption with KMS If the object was uploaded using a customer provided encryption key If the object is downloaded using range GetObject requests ダウンロード AWS CLIがS3からオブジェクトをダウンロードするたびに実行されるGetObjectリクエストから返されるETagヘッダーに基づいて、可能な場合はダウンロードのチェックサムを確認しようとします。計算されたMD5チェックサムが期待されるチェックサムと一致しない場合、ファイルは削除され、ダウンロードが再試行される。この処理は最大3回まで再試行される。ダウンロードに失敗した場合、AWS CLI は 0 以外の RC で終了する。詳細については、aws help return-codesを参照。 CLIがダウンロードのチェックサムを検証できない条件がいくつかある。 オブジェクトがマルチパートアップロードでアップロードされた場合 オブジェクトがKMSによるサーバーサイドの暗号化を使用してアップロードされた場合 顧客が提供した暗号化キーを使用してオブジェクトをアップロードした場合 オブジェクトが範囲 GetObject リクエストを使用してダウンロードされた場合 では、特定条件(マルチアップロード時やKMS暗号化している場合等)で整合性チェックが出来ない際にどうすれば良いのかというと、「ファイルをアップロードする前に、 ファイルの MD5 チェックサム値をアップロード後の整合性チェックの参照として使用することができます。」と書いてある通り、metadataを付与してダウンロード後にmd5値を確認するということになる。(実質的に整合性チェックツール等を作ることになる模様) Amazon S3 へのマルチパートアップロードに AWS CLI を使用する ファイルをアップロードする前に、 ファイルの MD5 チェックサム値をアップロード後の整合性チェックの参照として使用することができます。 aws s3 cp large_test_file s3://DOC-EXAMPLE-BUCKET/ --metadata md5="examplemd5value1234/4Q" --- ### S3オブジェクトのmd5やEtagの関係性について整理する date: 2022-01-10 url: https://zatoima.github.io/aws-s3-object-md5-etag/ tags: AWS, S3 色々とややこしいのでメモ。 用語 MD5:特定のファイルに対してツールによって算出された 16 進数を表す文字と数字からなる 32 文字の文字列。opensslコマンド等いくつか方法はあるが、md5sumコマンドだと下記の通りMD5値が出力される。 [ec2-user@bastin ~]$ dd if=/dev/zero of=~/test.txt bs=1M count=500 500+0 records in 500+0 records out 524288000 bytes (524 MB) copied, 0.233084 s, 2.2 GB/s [ec2-user@bastin ~]$ md5sum test.txt d8b61b2c0025919d5321461045c8226f test.txt Etag:HTTP のレスポンスヘッダーで、リソースの特定バージョンの識別子。URLにあるリソースに何かしらの変化があればETagも新しい値となる。 AWSにおけるETagの説明は下記の通り。S3の暗号化方式(SSE-S3 or SSE-KMS)でETagsの値が変わってくることとMultipart Upload または Part Copy 操作によって作成されたオブジェクトは、暗号化の方法に関係なく、MD5 ダイジェストではない ETag を持つことに特に注意。 Common Response Headers - Amazon Simple Storage Service ETag The entity tag represents a specific version of the object. The ETag reflects changes only to the contents of an object, not its metadata. The ETag may or may not be an MD5 digest of the object data. Whether or not it is depends on how the object was created and how it is encrypted as described below: Objects created through the AWS Management Console or by the PUT Object, POST Object, or Copy operation: Objects encrypted by SSE-S3 or plaintext have ETags that are an MD5 digest of their data. Objects encrypted by SSE-C or SSE-KMS have ETags that are not an MD5 digest of their object data. Objects created by either the Multipart Upload or Part Copy operation have ETags that are not MD5 digests, regardless of the method of encryption. 意訳 エンティティタグは、オブジェクトの特定のバージョンを表します。ETag は、オブジェクトの内容に対する変更のみを反映し、そのメタデータは反映しません。ETag はオブジェクトデータの MD5 ダイジェストであることもありますし、 そうでないこともあります。そうであるかどうかは、オブジェクトの作成方法と、以下に説明する暗号化の方法によって異なります。 AWS Management Console、またはPUT Object、POST Object、Copy操作によって作成されたオブジェクト。 SSE-S3または平文で暗号化されたオブジェクトは、そのデータのMD5ダイジェストであるETagsを持っています。 SSE-CまたはSSE-KMSによって暗号化されたオブジェクトは、そのオブジェクトデータのMD5ダイジェストではないETagsを持ちます。 Multipart Upload または Part Copy 操作によって作成されたオブジェクトは、暗号化の方法に関係なく、MD5 ダイジェストではない ETag を持ちます。 パターン①:SSE-S3または平文で暗号化されたオブジェクトの場合 バケットの設定 マルチアップロードの場合 マルチアップロードされているため、EC2側で取得したハッシュとS3上でのETagが異なる。 [ec2-user@bastin ~]$ dd if=/dev/zero of=~/test.txt bs=1M count=500 500+0 records in 500+0 records out 524288000 bytes (524 MB) copied, 0.23444 s, 2.2 GB/s [ec2-user@bastin ~]$ md5sum test.txt d8b61b2c0025919d5321461045c8226f test.txt [ec2-user@bastin ~]$ aws s3 cp ~/test.txt s3://s3-imazaj/ upload: ./test.txt to s3://s3-imazaj/test.txt [ec2-user@bastin ~]$ aws s3api head-object --bucket s3-imazaj --key test.txt { "AcceptRanges": "bytes", "LastModified": "Fri, 17 Dec 2021 13:11:36 GMT", "ContentLength": 524288000, "ETag": "\"2ab876e6e72b0fe9215ba306bea4f697-63\"", "VersionId": "f6twG5M7LGpjOzhGSIm9Tn1lnhnlN_ia", "ContentType": "text/plain", "ServerSideEncryption": "AES256", "Metadata": {} } 計算したい場合は下記ツール(※非公式)を使う。s3etagで出力されたハッシュとaws s3api head-objectで取得されたETagが同じであることがわかる。 [ec2-user@bastin ~]$ gem install s3etag Fetching: s3etag-0.0.1.gem (100%) Successfully installed s3etag-0.0.1 Parsing documentation for s3etag-0.0.1 Installing ri documentation for s3etag-0.0.1 1 gem installed [ec2-user@bastin ~]$ s3etag s3etag file -t, --thre[ec2-user@bastin ~]$ s3etag s3etag file -t, --threshold threshold -p, --max-parts max-parts -s, --min_part_size min_part_size [ec2-user@bastin ~]$ s3etag -t 8388608 -s 8388608 test.txt 2ab876e6e72b0fe9215ba306bea4f697-63 計算式は下記の通り。デフォルトのS3のマルチアップロード時の8MBで分割されるので8388608を指定している。 Again on ETAG and MD5 checksum for multipart ETag = MD5(Sum(p \in numberParts, MD5(PartBytes(p))) + "-" + numberParts 分割したファイルのMD5値を合算している 合算した値の末尾に – 分割数 を追記している。 S3上のオブジェクトのMD5値を取得したい場合、下記方法もある。 [ec2-user@bastin ~]$ sudo yum -y install s3cmd [ec2-user@bastin ~]$ s3cmd ls --list-md5 s3://s3-imazaj/ 2021-12-17 13:11 524288000 2ab876e6e72b0fe9215ba306bea4f697-63 s3://s3-imazaj/test.txt マルチアップロードではないパターン この場合はMD5=Etagとなる。 [ec2-user@bastin ~]$ md5sum test.txt d8b61b2c0025919d5321461045c8226f test.txt [ec2-user@bastin ~]$ aws s3api put-object --bucket s3-imazaj --key test.txt --body test.txt { "ETag": "\"d8b61b2c0025919d5321461045c8226f\"", "ServerSideEncryption": "AES256", "VersionId": "Einc9JkCj2itDk3BDSQJPAu1HoblkzfU" } [ec2-user@bastin ~]$ aws s3api head-object --bucket s3-imazaj --key test.txt { "AcceptRanges": "bytes", "LastModified": "Fri, 17 Dec 2021 13:20:58 GMT", "ContentLength": 524288000, "ETag": "\"d8b61b2c0025919d5321461045c8226f\"", "VersionId": "Einc9JkCj2itDk3BDSQJPAu1HoblkzfU", "ContentType": "binary/octet-stream", "ServerSideEncryption": "AES256", "Metadata": {} } [ec2-user@bastin ~]$ s3cmd ls --list-md5 s3://s3-imazaj/ 2021-12-17 13:20 524288000 d8b61b2c0025919d5321461045c8226f s3://s3-imazaj/test.txt パターン②:SSE-KMSによって暗号化されたオブジェクトの場合 S3バケットの設定 マルチアップロードの場合 [ec2-user@bastin ~]$ md5sum test.txt d8b61b2c0025919d5321461045c8226f test.txt [ec2-user@bastin ~]$ s3cmd ls --list-md5 s3://s3-imazaj/ 2021-12-17 13:20 524288000 d8b61b2c0025919d5321461045c8226f s3://s3-imazaj/test.txt [ec2-user@bastin ~]$ md5sum test.txt d8b61b2c0025919d5321461045c8226f test.txt [ec2-user@bastin ~]$ aws s3 cp test.txt s3://s3-imazaj/ upload: ./test.txt to s3://s3-imazaj/test.txt [ec2-user@bastin ~]$ aws s3api head-object --bucket s3-imazaj --key test.txt { "AcceptRanges": "bytes", "LastModified": "Fri, 17 Dec 2021 13:24:52 GMT", "ContentLength": 524288000, "ETag": "\"24a147ee52b41c94f398613a46a06810-63\"", "VersionId": "abQHe4HT0IMzx5biXy1olm6NqJKkk8Cs", "ContentType": "text/plain", "ServerSideEncryption": "aws:kms", "Metadata": {}, "SSEKMSKeyId": "arn:aws:kms:ap-northeast-1:xxxxxxxxxxxxx:key/d2c7662c-19fa-40d2-a348-bbc2d7e79f6e", "BucketKeyEnabled": true } [ec2-user@bastin ~]$ s3cmd ls --list-md5 s3://s3-imazaj/ 2021-12-17 13:24 524288000 24a147ee52b41c94f398613a46a06810-63 s3://s3-imazaj/test.txt s3etagツールを使ってもEtagとMD5値が合わなくなる [ec2-user@bastin ~]$ s3etag -t 8388608 -s 8388608 test.txt 2ab876e6e72b0fe9215ba306bea4f697-63 ≠マルチアップロード 暗号化使っている場合はマルチアップロードでないパターンでもNGとなる。 [ec2-user@bastin ~]$ aws s3api put-object --bucket s3-imazaj --key test.txt --body test.txt { "ETag": "\"dd6006c0c101d532e17cb992b04658b0\"", "ServerSideEncryption": "aws:kms", "VersionId": "8k7ceRD0TRNWLTmiQlaqersys_0nZgln", "SSEKMSKeyId": "arn:aws:kms:ap-northeast-1:xxxxxxxxxxxxx:key/d2c7662c-19fa-40d2-a348-bbc2d7e79f6e", "BucketKeyEnabled": true } [ec2-user@bastin ~]$ aws s3api head-object --bucket s3-imazaj --key test.txt { "AcceptRanges": "bytes", "LastModified": "Fri, 17 Dec 2021 13:26:25 GMT", "ContentLength": 524288000, "ETag": "\"dd6006c0c101d532e17cb992b04658b0\"", "VersionId": "8k7ceRD0TRNWLTmiQlaqersys_0nZgln", "ContentType": "binary/octet-stream", "ServerSideEncryption": "aws:kms", "Metadata": {}, "SSEKMSKeyId": "arn:aws:kms:ap-northeast-1:xxxxxxxxxxxxx:key/d2c7662c-19fa-40d2-a348-bbc2d7e79f6e", "BucketKeyEnabled": true } 参考 S3へコピーしたデータが、本当にコピー元と同一かどうか検証してみた時のお話 - Qiita S3マルチパートアップロードのETagの値 | レコチョクのエンジニアブログ --- ### ECRへのコンテナイメージのPush、Pullのメモ date: 2022-01-07 url: https://zatoima.github.io/aws-ecr-container-push-pull/ tags: AWS, ECR ECRへのPush mkdir aipine-docker cd aipine-docker cat > Dockerfile << 'EOF' FROM alpine:latest RUN apk --update add ruby && rm -rf /var/cache/apk/* EOF docker build -t xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/sample-fargate . aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com docker push xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/sample-fargate aws ecr list-images --repository-name sample-fargate 実行ログ [ec2-user@bastin ~]$ mkdir aipine-docker [ec2-user@bastin ~]$ cd aipine-docker [ec2-user@bastin aipine-docker]$ [ec2-user@bastin aipine-docker]$ cat > Dockerfile << 'EOF' > FROM alpine:latest > RUN apk --update add ruby && rm -rf /var/cache/apk/* > EOF [ec2-user@bastin aipine-docker]$ [ec2-user@bastin aipine-docker]$ docker build -t xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/sample-fargate . Sending build context to Docker daemon 2.048kB Step 1/2 : FROM alpine:latest ---> c059bfaa849c Step 2/2 : RUN apk --update add ruby && rm -rf /var/cache/apk/* ---> Using cache ---> d5cd040a87f2 Successfully built d5cd040a87f2 Successfully tagged xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/sample-fargate:latest [ec2-user@bastin aipine-docker]$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com WARNING! Your password will be stored unencrypted in /home/ec2-user/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded [ec2-user@bastin aipine-docker]$ docker push xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/sample-fargate Using default tag: latest The push refers to repository [xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/sample-fargate] 8a1cebaa0140: Pushed 8d3ac3489996: Layer already exists latest: digest: sha256:40f2fd6d282ff49e0f0b7cb973df0f443338bcef6f40bdc20b578073d9945b18 size: 739 [ec2-user@bastin aipine-docker]$ aws ecr list-images --repository-name sample-fargate { "imageIds": [ { "imageDigest": "sha256:40f2fd6d282ff49e0f0b7cb973df0f443338bcef6f40bdc20b578073d9945b18", "imageTag": "latest" } ] } [ec2-user@bastin aipine-docker]$ ECRからコンテナイメージをpullする aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com docker pull xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/sample-fargate:latest docker images 実行ログ [ec2-user@bastin aipine-docker]$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com WARNING! Your password will be stored unencrypted in /home/ec2-user/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded [ec2-user@bastin aipine-docker]$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/sample-fargate latest d5cd040a87f2 11 minutes ago 20.1MB alpine latest c059bfaa849c 5 weeks ago 5.59MB [ec2-user@bastin aipine-docker]$ [ec2-user@bastin aipine-docker]$ docker pull xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/sample-fargate:latest latest: Pulling from sample-fargate Digest: sha256:40f2fd6d282ff49e0f0b7cb973df0f443338bcef6f40bdc20b578073d9945b18 Status: Image is up to date for xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/sample-fargate:latest xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/sample-fargate:latest --- ### PostgreSQLでMerge/Upsertを実行したら遅かったので力技で解決した date: 2022-01-05 url: https://zatoima.github.io/postgres-merge-upsert-tuning/ tags: PostgreSQL 検証用環境の作成 テーブル作成 drop table t1; create table t1(a numeric,b varchar(100) ,c varchar(100) ,d varchar(100) ,e varchar(100) , f varchar(100) , g varchar(100) , h varchar(100) , i varchar(100) , j varchar(100) , k varchar(100) , l varchar(100) , m varchar(100) , n varchar(100) ); drop table t2_delta; create table t2_delta(a numeric,b varchar(100) ,c varchar(100) ,d varchar(100) ,e varchar(100) , f varchar(100) , g varchar(100) , h varchar(100) , i varchar(100) , j varchar(100) , k varchar(100) , l varchar(100) , m varchar(100) , n varchar(100) ); ALTER TABLE t1 DROP CONSTRAINT t1_PKEY; ALTER TABLE t1 ADD CONSTRAINT t1_PKEY PRIMARY KEY(a,b,c,d); データ作成 truncate table t1; insert into t1 SELECT i, i+1, i*2 ,i/2 ,string_agg(str, '') ,string_agg(str, '') ,string_agg(str, '') ,string_agg(str, '') ,string_agg(str, '') ,string_agg(str, '') ,string_agg(str, '') ,string_agg(str, '') ,string_agg(str, '') ,string_agg(str, '') FROM (SELECT md5(clock_timestamp()::text) as str , i FROM generate_series(1,2) length, generate_series(1,10) num(i) )t GROUP BY i; truncate table t2_delta; insert into t2_delta SELECT i, i+1, i*2 ,i/2 ,string_agg(str, '') ,string_agg(str, '') ,string_agg(str, '') ,string_agg(str, '') ,string_agg(str, '') ,string_agg(str, '') ,string_agg(str, '') ,string_agg(str, '') ,string_agg(str, '') ,string_agg(str, '') FROM (SELECT md5(clock_timestamp()::text) as str , i FROM generate_series(1,2) length, generate_series(1,10000000) num(i) )t GROUP BY i; 1000万規模のUPSERT処理の実行 UPSERT処理 explain analyze INSERT INTO t1(a,b,c,d,e,f,g,h,i,j,k,l,m,n) SELECT src.a, src.b, src.c, src.d, src.e, src.f, src.g, src.h, src.i, src.j, src.k, src.l, src.m, src.n FROM ( SELECT a,b,c,d,e,f,g,h,i,j,k,l,m,n FROM t2_delta ) src ON CONFLICT ON CONSTRAINT t1_PKEY DO UPDATE SET a = excluded.a, b = excluded.b, c = excluded.c, d = excluded.d, f = excluded.f, g = excluded.g, h = excluded.h, i = excluded.i, j = excluded.j, k = excluded.k, l = excluded.l, m = excluded.m, n = excluded.n ; このUPSERT時の実行計画 キャッシュにテーブルとインデックスがない場合に非常に時間が掛かった。2407秒。PostgreSQLのInsert on Conflictの場合の実行計画はどこがボトルネックになっているのか分かりづらい。 ---------------------------------------------------------------------------------------------------------------------------------- Insert on t1 (cost=0.00..1009091.01 rows=10000001 width=678) (actual time=2407550.457..2407550.458 rows=0 loops=1) Conflict Resolution: UPDATE Conflict Arbiter Indexes: t1_pkey Tuples Inserted: 0 Conflicting Tuples: 10000000 -> Seq Scan on t2_delta (cost=0.00..1009091.01 rows=10000001 width=678) (actual time=2.484..10999.718 rows=10000000 loops=1) Planning Time: 0.143 ms Execution Time: 2407607.917 ms (8 rows) 実行時の待機イベントをPerformance insightsで確認したところIO待ちがほとんどに… 力技でバッファキャッシュに乗せて再実行したら早くなった。2407秒から398秒へ create extension pg_prewarm; SELECT pg_prewarm('t1', 'buffer', 'main') ,pg_prewarm('t2_delta', 'buffer', 'main') ,pg_prewarm('t1_pkey', 'buffer', 'main') ; create extension pg_buffercache; select c.relname, count(*) as buffers from pg_buffercache as b inner join pg_class as c on b.relfilenode = pg_relation_filenode(c.oid) and b.reldatabase in (0, (select oid from pg_database where datname = current_database())) group by c.relname order by 2 desc; --------------------------------------------------------------------------------------------------------------------------------- Insert on t1 (cost=0.00..1009091.01 rows=10000001 width=678) (actual time=398525.649..398525.650 rows=0 loops=1) Conflict Resolution: UPDATE Conflict Arbiter Indexes: t1_pkey Tuples Inserted: 0 Conflicting Tuples: 10000000 -> Seq Scan on t2_delta (cost=0.00..1009091.01 rows=10000001 width=678) (actual time=0.013..2481.678 rows=10000000 loops=1) Planning Time: 0.944 ms Execution Time: 398550.088 ms (8 rows) --- ### PostgreSQLでMerge/Upsertを行う date: 2022-01-04 url: https://zatoima.github.io/postgres-merge-upsert/ tags: PostgreSQL" PostgreSQLの場合はMerge文というものはなくInsert on conflictを使うことになる。昔はCTE(共通テーブル式)を使ってUPSERT処理を行っていた模様。注意点としてはon conflictのところで制約が必要なくらい。 テーブル作成 drop table PRODUCT; CREATE TABLE PRODUCT ( product_name CHARACTER VARYING(50), product_type CHARACTER VARYING (10), unit_price DOUBLE PRECISION, modified_date TIMESTAMP ); ALTER TABLE PRODUCT ADD CONSTRAINT PRODUCT_PKEY PRIMARY KEY(product_name, product_type); drop table PRODUCT; CREATE TABLE PRODUCT_DELTA ( product_name CHARACTER VARYING (50), product_type CHARACTER VARYING (10), unit_price DOUBLE PRECISION, status CHAR(1) ); データ準備 --Insert into PRODUCT table INSERT INTO PRODUCT(product_name, product_type, unit_price, modified_date) VALUES('PR1', 'A', 10, '2020-01-01'); INSERT INTO PRODUCT(product_name, product_type, unit_price, modified_date) VALUES('PR2', 'C', 10, '2020-01-01'); INSERT INTO PRODUCT(product_name, product_type, unit_price, modified_date) VALUES('PR3', 'B', 10, '2020-01-01'); INSERT INTO PRODUCT(product_name, product_type, unit_price, modified_date) VALUES('PR4', 'B', 10, '2020-01-01'); INSERT INTO PRODUCT(product_name, product_type, unit_price, modified_date) VALUES('PR10', 'A', 10, '2020-01-01'); -- insert into PRODUCT_DELTA table INSERT INTO PRODUCT_DELTA(product_name, product_type, unit_price, status) VALUES('PR1', 'A', 20, 'Y'); INSERT INTO PRODUCT_DELTA(product_name, product_type, unit_price, status) VALUES('PR2', 'C', 20, 'N'); INSERT INTO PRODUCT_DELTA(product_name, product_type, unit_price, status) VALUES('PR5', 'F', 20, 'N'); INSERT INTO PRODUCT_DELTA(product_name, product_type, unit_price, status) VALUES('PR6', 'B', 20, 'N'); upsert/merge INSERT INTO PRODUCT(product_name, product_type, unit_price, modified_date) SELECT src.product_name, src.product_type, src.unit_price, now() modified_date FROM ( SELECT product_name, product_type, unit_price FROM PRODUCT_DELTA ) src ON CONFLICT(product_name, product_type) DO UPDATE SET unit_price = excluded.unit_price, modified_date = excluded.modified_date; 実行ログ postgres=> CREATE TABLE PRODUCT ( postgres(> product_name CHARACTER VARYING(50), postgres(> product_type CHARACTER VARYING (10), postgres(> unit_price DOUBLE PRECISION, postgres(> modified_date TIMESTAMP postgres(> ); CREATE TABLE postgres=> ALTER TABLE PRODUCT postgres-> ADD CONSTRAINT PRODUCT_PKEY PRIMARY KEY(product_name, product_type); ALTER TABLE postgres=> CREATE TABLE PRODUCT_DELTA ( postgres(> product_name CHARACTER VARYING (50), postgres(> product_type CHARACTER VARYING (10), postgres(> unit_price DOUBLE PRECISION, postgres(> status CHAR(1) postgres(> ); CREATE TABLE postgres=> INSERT INTO PRODUCT(product_name, product_type, unit_price, modified_date) VALUES('PR1', 'A', 10, '2020-01-01'); ce, modified_date) VALUES('PR10', 'A', 10, '2020-01-01');INSERT 0 1 postgres=> INSERT INTO PRODUCT(product_name, product_type, unit_price, modified_date) VALUES('PR2', 'C', 10, '2020-01-01'); INSERT 0 1 postgres=> INSERT INTO PRODUCT(product_name, product_type, unit_price, modified_date) VALUES('PR3', 'B', 10, '2020-01-01'); INSERT 0 1 postgres=> INSERT INTO PRODUCT(product_name, product_type, unit_price, modified_date) VALUES('PR4', 'B', 10, '2020-01-01'); INSERT 0 1 postgres=> INSERT INTO PRODUCT(product_name, product_type, unit_price, modified_date) VALUES('PR10', 'A', 10, '2020-01-01'); INSERT 0 1 postgres=> postgres=> INSERT INTO PRODUCT_DELTA(product_name, product_type, unit_price, status) VALUES('PR1', 'A', 20, 'Y'); INSERT 0 1 postgres=> INSERT INTO PRODUCT_DELTA(product_name, product_type, unit_price, status) VALUES('PR2', 'C', 20, 'N'); INSERT 0 1 postgres=> INSERT INTO PRODUCT_DELTA(product_name, product_type, unit_price, status) VALUES('PR5', 'F', 20, 'N'); INSERT 0 1 postgres=> INSERT INTO PRODUCT_DELTA(product_name, product_type, unit_price, status) VALUES('PR6', 'B', 20, 'N'); INSERT 0 1 postgres=> postgres=> postgres=> select * from PRODUCT; product_name | product_type | unit_price | modified_date --------------+--------------+------------+--------------------- PR1 | A | 10 | 2020-01-01 00:00:00 PR2 | C | 10 | 2020-01-01 00:00:00 PR3 | B | 10 | 2020-01-01 00:00:00 PR4 | B | 10 | 2020-01-01 00:00:00 PR10 | A | 10 | 2020-01-01 00:00:00 (5 rows) postgres=> select * from PRODUCT_DELTA; product_name | product_type | unit_price | status --------------+--------------+------------+-------- PR1 | A | 20 | Y PR2 | C | 20 | N PR5 | F | 20 | N PR6 | B | 20 | N (4 rows) postgres=> postgres=> INSERT INTO PRODUCT(product_name, product_type, unit_price, modified_date) postgres-> SELECT src.product_name, postgres-> src.product_type, postgres-> src.unit_price, postgres-> now() modified_date postgres-> FROM ( SELECT postgres(> postgres(> product_name, postgres(> product_type, postgres(> unit_price postgres(> FROM PRODUCT_DELTA postgres(> ) src postgres-> ON CONFLICT(product_name, product_type) postgres-> DO UPDATE postgres-> SET postgres-> unit_price = excluded.unit_price, postgres-> modified_date = excluded.modified_date; INSERT 0 4 postgres=> postgres=> select * from PRODUCT postgres-> ; product_name | product_type | unit_price | modified_date --------------+--------------+------------+---------------------------- PR3 | B | 10 | 2020-01-01 00:00:00 PR4 | B | 10 | 2020-01-01 00:00:00 PR10 | A | 10 | 2020-01-01 00:00:00 PR1 | A | 20 | 2021-12-23 05:42:30.980878 PR2 | C | 20 | 2021-12-23 05:42:30.980878 PR5 | F | 20 | 2021-12-23 05:42:30.980878 PR6 | B | 20 | 2021-12-23 05:42:30.980878 (7 rows) postgres=> postgres=> explain analyze postgres-> INSERT INTO PRODUCT(product_name, product_type, unit_price, modified_date) postgres-> SELECT src.product_name, postgres-> src.product_type, postgres-> src.unit_price, postgres-> now() modified_date postgres-> FROM ( SELECT postgres(> postgres(> product_name, postgres(> product_type, postgres(> unit_price postgres(> FROM PRODUCT_DELTA postgres(> ) src postgres-> ON CONFLICT(product_name, product_type) postgres-> DO UPDATE postgres-> SET postgres-> unit_price = excluded.unit_price, postgres-> modified_date = excluded.modified_date; QUERY PLAN ------------------------------------------------------------------------------------------------------------------ Insert on product (cost=0.00..16.00 rows=400 width=172) (actual time=0.115..0.116 rows=0 loops=1) Conflict Resolution: UPDATE Conflict Arbiter Indexes: product_pkey Tuples Inserted: 0 Conflicting Tuples: 4 -> Seq Scan on product_delta (cost=0.00..16.00 rows=400 width=172) (actual time=0.014..0.016 rows=4 loops=1) Planning time: 0.056 ms Execution time: 0.142 ms (8 rows) 参考 Best practices for migrating Oracle database MERGE statements to Amazon Aurora PostgreSQL and Amazon RDS PostgreSQL | AWS Database Blog --- ### Amazon LinuxにMongoDB(5.x系)をインストールする date: 2021-12-30 url: https://zatoima.github.io/aws-mongodb-install/ tags: AWS, MongoDB Linuxのディストリビューションの確認 grep ^NAME /etc/*release [ec2-user@bastin ~]$ grep ^NAME /etc/*release /etc/os-release:NAME="Amazon Linux" インストール準備 mongodb-org-5.0.repoを作成 sudo vi /etc/yum.repos.d/mongodb-org-5.0.repo [mongodb-org-5.0] name=MongoDB Repository baseurl=https://repo.mongodb.org/yum/amazon/2/mongodb-org/5.0/x86_64/ gpgcheck=1 enabled=1 gpgkey=https://www.mongodb.org/static/pgp/server-5.0.asc yumでインストール 最新のmongodbがインストールされる sudo yum install -y mongodb-org mongo -version MongoDBの起動 sudo systemctl start mongod MongoDBの起動確認 sudo systemctl status mongod MongoDBの再起動 sudo systemctl restart mongod OS起動と同時にプロセスを起動したい場合 sudo systemctl enable mongod バージョン確認 [ec2-user@bastin ~]$ mongo MongoDB shell version v3.6.23 connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb Implicit session: session { "id" : UUID("c2030c87-8f92-4fdd-8b93-6265be9fdc28") } MongoDB server version: 5.0.5 WARNING: shell and server versions do not match Server has startup warnings: {"t":{"$date":"2021-12-30T21:38:38.651+09:00"},"s":"W", "c":"CONTROL", "id":22120, "ctx":"initandlisten","msg":"Access control is not enabled for the database. Read and write access to data and configuration is unrestricted","tags":["startupWarnings"]} > db.version() 5.0.5 データ挿入と確認 > db.stats() { "db" : "test", "collections" : 0, "views" : 0, "objects" : 0, "avgObjSize" : 0, "dataSize" : 0, "storageSize" : 0, "totalSize" : 0, "indexes" : 0, "indexSize" : 0, "scaleFactor" : 1, "fileSize" : 0, "fsUsedSize" : 0, "fsTotalSize" : 0, "ok" : 1 } > > db.user.insert({name:'mr.a', age:10, gender:'m', hobbies:['programming']}); WriteResult({ "nInserted" : 1 }) > db.user.insert({name:'mr.b', age:20, gender:'m', hobbies:['vi']}); WriteResult({ "nInserted" : 1 }) > db.user.insert({name:'ms.c', age:30, gender:'f', hobbies:['programming', 'vi']}); WriteResult({ "nInserted" : 1 }) > db.user.insert({name:'ms.d', age:40, gender:'f', hobbies:['cooking']}); WriteResult({ "nInserted" : 1 }) > > db.user.find() { "_id" : ObjectId("61cda8e0f9bdc7753af20459"), "name" : "mr.a", "age" : 10, "gender" : "m", "hobbies" : [ "programming" ] } { "_id" : ObjectId("61cda8e0f9bdc7753af2045a"), "name" : "mr.b", "age" : 20, "gender" : "m", "hobbies" : [ "vi" ] } { "_id" : ObjectId("61cda8e0f9bdc7753af2045b"), "name" : "ms.c", "age" : 30, "gender" : "f", "hobbies" : [ "programming", "vi" ] } { "_id" : ObjectId("61cda8e0f9bdc7753af2045c"), "name" : "ms.d", "age" : 40, "gender" : "f", "hobbies" : [ "cooking" ] } > db.stats() { "db" : "test", "collections" : 1, "views" : 0, "objects" : 4, "avgObjSize" : 96.25, "dataSize" : 385, "storageSize" : 20480, "freeStorageSize" : 0, "indexes" : 1, "indexSize" : 20480, "indexFreeStorageSize" : 0, "totalSize" : 40960, "totalFreeStorageSize" : 0, "scaleFactor" : 1, "fsUsedSize" : 206759358464, "fsTotalSize" : 214735761408, "ok" : 1 } 参考 Install MongoDB Community Edition on Amazon Linux — MongoDB Manual https://docs.mongodb.com/manual/tutorial/install-mongodb-on-amazon/ --- ### PostgreSQLでバッファキャッシュ上にデータをのせる date: 2021-12-29 url: https://zatoima.github.io/postgres-extension-pg-prewarm-buffer-cache/ tags: PostgreSQL pg_prewarmとpg_buffercacheで確認 pg_prewarm 忘れがちだが、テーブルだけではなくインデックスも対象に出来る create extension pg_prewarm; SELECT pg_prewarm('t1', 'buffer', 'main') ,pg_prewarm('t2_delta', 'buffer', 'main') ,pg_prewarm('t1_PKEY', 'buffer', 'main') ; pg_buffercache create extension pg_buffercache; select c.relname, count(*) as buffers from pg_buffercache as b inner join pg_class as c on b.relfilenode = pg_relation_filenode(c.oid) and b.reldatabase in (0, (select oid from pg_database where datname = current_database())) group by c.relname order by 2 desc LIMIT 30; 実行ログ postgres=> SELECT postgres-> pg_prewarm('t1', 'buffer', 'main') postgres-> ,pg_prewarm('t2_delta', 'buffer', 'main') postgres-> ,pg_prewarm('t1_PKEY', 'buffer', 'main') postgres-> ; pg_prewarm | pg_prewarm | pg_prewarm ------------+------------+------------ 1818182 | 909091 | 54840 (1 row) postgres=> select c.relname, count(*) as buffers postgres-> from pg_buffercache as b postgres-> inner join pg_class as c on b.relfilenode = pg_relation_filenode(c.oid) and b.reldatabase in (0, (select oid from pg_database where datname = current_database())) postgres-> group by c.relname postgres-> order by 2 desc postgres-> LIMIT 30; relname | buffers -----------------------------------+--------- t1 | 1818687 t2_delta | 909091 t1_idx | 426172 t1_pkey | 54840 pg_attribute | 60 pg_toast_2619 | 36 pg_class | 13 pg_proc | 12 pg_statistic | 11 pg_attribute_relid_attnum_index | 9 pg_proc_oid_index | 8 pg_proc_proname_args_nsp_index | 6 pg_amop | 6 pg_class_relname_nsp_index | 5 pg_amproc | 4 pg_operator | 4 pg_class_oid_index | 4 pg_statistic_relid_att_inh_index | 4 pg_index | 4 pg_amop_opr_fam_index | 4 pg_operator_oid_index | 4 pg_type | 3 pg_amop_fam_strat_index | 3 pg_type_oid_index | 3 pg_operator_oprname_l_r_n_index | 3 pg_amproc_fam_proc_index | 3 pg_depend_reference_index | 3 pg_type_typname_nsp_index | 3 pg_auth_members_member_role_index | 2 pg_cast_source_target_index | 2 (30 rows) postgres=> --- ### AWSで東京リージョンから大阪リージョンへのリージョン間のアウトバウンド通信コストを確認 date: 2021-12-26 url: https://zatoima.github.io/aws-tokyo-to-osaka-network-outbound-cost/ tags: AWS, Aurora Cost Explolerのレポートで確認出来る。右側のフィルターで使用タイプでAPN1-APN3-AWS-Out-Bytesを指定する。グループ化の条件としてサービスを指定することでどのサービスの転送量が多いのかが分かる。 Cost Explorerをもっと使いこなしたい。 参考 【AWS CLI】Cost Explorer編 - サーバーワークスエンジニアブログ https://d1.awsstatic.com/webinars/jp/pdf/services/20200129_BlackBelt_CostExplorer.pdf --- ### AuroraのIO料金をCost Explolerから確認する date: 2021-12-24 url: https://zatoima.github.io/aws-aurora-io-cost-exploler-check/ tags: AWS, Aurora Cost Explolerのレポートを開く https://console.aws.amazon.com/cost-management/home#/dashboard 右側のフィルター部分で下記の通り指定する。適宜集計する期間も変更する。左上部分。 サービスでRDSを選択する Aurora:StorageIOUsage (IOs)を使用タイプで検索して該当する使用タイプを全部選択する カーソルをグラフにあてるとIO数とコストが確認可能。 --- ### PostgreSQLのpostgres_fdw拡張機能の実行 date: 2021-12-21 url: https://zatoima.github.io/postgres-extension-fdw-install/ tags: PostgreSQL postgres_fdwの実行 拡張機能の有効化 CREATE EXTENSION postgres_fdw; 外部サーバの定義 test1データベースに対しての外部サーバを作成する CREATE SERVER fdw_app FOREIGN DATA WRAPPER postgres_fdw OPTIONS (dbname 'test1'); 外部サーバのユーザーマップ定義 CREATE USER MAPPING FOR public SERVER fdw_app OPTIONS (user 'postgres', password 'postgres'); 外部テーブルの作成 fdw_app外部サーバを使用してt2テーブルを外部テーブルとして作成する CREATE FOREIGN TABLE t2 (a integer, b text,c text, d timestamp with time zone) SERVER fdw_app; 外部テーブルの場合はtypeがforeign tableになる模様 postgres=> \d List of relations Schema | Name | Type | Owner --------+-------------+---------------+---------- public | t1 | table | postgres public | t2 | foreign table | postgres public | v_dblink_t1 | view | postgres IMPORT FOREIGN SCHEMAを使用して外部テーブルの作成も可能。 検索 postgres=> select count(*) from t2; count ----------- 100000000 (1 row) postgres_fdwの特徴 プッシュダウン機能 SQL文に含まれるWHERE句(絞り込み処理)、ORDER BY句(ソート処理)などをリモート側で実行される dblinkと違う明確なメリット 更新が可能 ON CONFLICT DO UPDATE句のあるINSERT文をサポートしていない postgres_fdwの注意点 トランザクションの制御 リモート側のCOMMITのタイミング、トランザクション分離レベルで注意が必要(詳細は参考のリンクを) 性能面 通信量次第で遅くなる傾向にある リモート実行オプションでfetch_sizeが100なので、必要に応じてチューニングする必要がある 参考 F.33. postgres_fdw https://www.postgresql.jp/document/13/html/postgres-fdw.html PostgreSQL 9.6 の postgres_fdw について検証してみた | SIOS Tech. Lab https://tech-lab.sios.jp/archives/8641#i 外部データとの連携 ~FDWで様々なデータソースとつなぐ~|PostgreSQLインサイド : 富士通 https://www.fujitsu.com/jp/products/software/resources/feature-stories/postgres/article-index/fdw-overview/ --- ### PostgreSQLのdblink拡張機能の実行と注意点 date: 2021-12-19 url: https://zatoima.github.io/postgres-extension-dblink-install-and-causion/ tags: PostgreSQL postgres_fdwではなくdblinkの話。環境はAurora PostgreSQLで実行 dblink https://www.postgresql.jp/document/13/html/contrib-dblink-function.html dblinkの実行 dblinkのインストール postgres=> \dx List of installed extensions Name | Version | Schema | Description ---------+---------+------------+------------------------------ plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language (1 row) postgres=> create extension dblink; CREATE EXTENSION postgres=> \dx List of installed extensions Name | Version | Schema | Description ---------+---------+------------+-------------------------------------------------------------- dblink | 1.2 | public | connect to other PostgreSQL databases from within a database plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language (2 rows) postgres=> 事前準備:データベースとテーブル作成 test1データベースのt1テーブルをdblinkで別データベースから取得する。そのためのデータベースとテーブル作成。 create database test1; \c test1; create table t1(a numeric primary key, b varchar(30)); insert into t1 values(1,'this data is at test1 database'); 方法1:コネクションを生成して接続する方法 コネクションの生成 postgres=> select dblink_connect('dblink-test1','dbname=test1 user=postgres password=postgres'); dblink_connect ---------------- OK (1 row) 検索 検索時にはリモートテーブル側のデータ型まで記載する必要がある postgres=> select * from dblink('dblink-test1','select a,b from t1') as t1(a numeric, b varchar(30)) ; a | b ---+-------------------------------- 1 | this data is at test1 database (1 row) データ型がないと下記の通り、怒られる postgres=> select * from dblink('dblink-test1','select a,b from t1'); ERROR: a column definition list is required for functions returning "record" LINE 1: select * from dblink('dblink-test1','select a,b from t1'); 切断 postgres=> select dblink_disconnect('dblink-test1'); dblink_disconnect ------------------- OK (1 row) 切断後は当然エラーとなる postgres=> select * from dblink('dblink-test1','select a,b from t1') as t1(a numeric, b varchar(30)) ; ERROR: password is required DETAIL: Non-superusers must provide a password in the connection string. postgres=> 方法2:コネクションを生成せずに接続する方法 postgres=> select * from dblink('dbname=test1 user=postgres password=postgres','select a,b from t1') as t1(a numeric, b varchar(30)) ; a | b ---+-------------------------------- 1 | this data is at test1 database (1 row) 注意点 独特なdblink用のSQL構文 上記で記載した通り、リモート側のデータ型を一つ一つ記載する必要がある。マニュアル的にはviewを使って簡単に記載してくださいとのこと。 https://www.postgresql.jp/document/13/html/contrib-dblink-function.html 前もって判明している問い合わせをdblinkで使用する簡便な方法はビューを作成することです。 これにより問い合わせの度に列型の情報を記載することなく、ビュー内に隠すことができます。 以下に例を示します。 CREATE VIEW myremote_pg_proc AS SELECT * FROM dblink('dbname=postgres options=-csearch_path=', 'select proname, prosrc from pg_proc') AS t1(proname name, prosrc text); SELECT * FROM myremote_pg_proc WHERE proname LIKE 'bytea%'; リモートテーブルとローカルテーブルを結合したりする際に全量をローカルに転送してから結合処理やWHERE句による絞り込みを行う必要があり、表によっては大量のデータを転送することになり、非効率な実行計画となる。インデックスを付けていても有無を言わさず全てを持ってくる。同じサーバ内の通信であればどうにかなるケースがあるかもしれないがネットワーク経由の通信の場合、帯域が気になる。同じサーバ内でも通信量次第でボトルネックになる可能性がある。単純に全件データを持ってくることがそもそも辛い。 下記は、t1がローカルテーブル、t2がリモートテーブル。t2.a=10を指定しており、インデックスを貼っているので1件だけ取ってくれれば嬉しいが、そういう実行計画になっていない。実行時間も非常に時間がかかっている postgres=> explain analyze select t1.d from dblink('dbname=test1 user=postgres password=postgres','select a from t2') as t2(a integer), t1 where t1.a=t2.a and t2.a=10; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------- Nested Loop (cost=0.00..13.68 rows=5 width=8) (actual time=50611.640..58457.467 rows=1 loops=1) -> Seq Scan on t1 (cost=0.00..1.12 rows=1 width=12) (actual time=1.910..1.914 rows=1 loops=1) Filter: (a = 10) Rows Removed by Filter: 9 -> Function Scan on dblink t2 (cost=0.00..12.50 rows=5 width=4) (actual time=50609.726..58455.547 rows=1 loops=1) Filter: (a = 10) Rows Removed by Filter: 99999999 Planning time: 41.712 ms Execution time: 58712.667 ms (9 rows) dblink での問合せは、別のトランザクションとして扱われるので、実行中のトランザクションとの整合性を保証するには、二相コミットの検討が必要 まとめ データベースリンク機能であれば後継的扱いのpostgres_fdwを使った方が良い。 https://www.postgresql.jp/document/13/html/postgres-fdw.html 実質上、本モジュールの提供する機能は以前のdblinkモジュールが提供する機能と重複していますが、postgres_fdwはリモートのテーブルにアクセスするためにより透過的で標準に準拠した構文を利用できるほか、多くの場合においてより良い性能を得る事ができます。 参考 dblink https://www.postgresql.jp/document/13/html/contrib-dblink-function.html dblink | Let’s POSTGRES https://lets.postgresql.jp/documents/technical/contrib/dblink PostgreSQL9.3 新機能を検証してみた Vol.2 | アシスト https://www.ashisuto.co.jp/corporate/column/technical-column/detail/1198469_2274.html --- ### Hugo AcademicのError failed to resolve output formatエラーについて date: 2021-12-16 url: https://zatoima.github.io/hugo-error-build-output-format/ tags: Hugo Hugo Academicのエラーと対応の備忘。 エラー 下記のエラーが出てビルド出来ない状態。 C:\hugo\zatoima.github.io>start http://localhost:1313/ C:\hugo\zatoima.github.io>hugo server hugo: collected modules in 1055 ms Error: from config: failed to resolve output format "headers" from site config 対応 AppData\Local\Temp配下にhugo_cacheディレクトリがあるのでそれを削除したら問題無くビルド出来るように。 参照先 https://wowchemy.com/docs/hugo-tutorials/troubleshooting/#error-file-not-found-or-failed-to-extract Error: failed to resolve output format Users report a commonly occurring Hugo issue with the integrity of the modules cache. Consider upvoting and commenting on the issue to show the Hugo team that you are also affected. To resolve this Hugo issue, either: (A) Manually delete Hugo’s default cache folder and re-run Hugo. Hugo’s cache folder defaults to $TMPDIR/hugo_cache/ on Mac/Linux and %TMP%\hugo_cache\ on Windows. Or, (B) Set a custom Hugo cache folder when you run Hugo, for example: hugo server --cacheDir ./cache/ where ./cache/ is the path of a temporary folder to create. Then you can easily locate and delete Hugo’s cache folder should you experience this issue. Note: usually hugo mod clean --all should delete Hugo’s cache, however, users report a Hugo bug running the command in this situation. You can provide your feedback on the Hugo issues. 日本語訳 by DeepL モジュールキャッシュの整合性に関して、Hugoでよく発生する問題がユーザーから報告されています。Hugo チームに自分も影響を受けていることを示すために、この問題に upvoting や commenting することを検討してください。 この Hugo の問題を解決するには、以下のいずれかを行ってください。 (A) Hugo のデフォルトのキャッシュフォルダを手動で削除し、Hugo を再実行します。Hugoのキャッシュフォルダのデフォルトは、Mac/Linuxでは$TMPDIR/hugo_cache/、Windowsでは%TMP%hugo_cacheです。 あるいは、(B) Hugo を実行するときに、カスタム Hugo キャッシュフォルダを設定します。例えば、 hugo server –cacheDir ./cache/ ここで ./cache/ は作成する一時フォルダのパスとなります。そうすれば、この問題が発生したときに、Hugoのキャッシュフォルダを簡単に見つけて削除することができます。 --- ### ドッキングステーション購入の失敗談メモ date: 2021-12-15 url: https://zatoima.github.io/other-docking-station/ tags: その他 前提 下記の2台を必要なときにそれぞれドッキングステーションに繋げてWQHD(2,560×1,440)モニター2枚に接続してデュアルディスプレイ環境にしたかった。キーボードやマウス、その他ワイヤレスヘッドフォン等をドッキングステーションに繋げて外部機器を共用したかった。 ① thunderbolt3対応の仕事用PC ② thunderbolt3非対応(usb type-c)のPC 現状 Thunderbolt™ 3 Dock Pro for Mac & PC USB Type-Cのデバイス対応と謳っているにも関わらず、下記の注意事項がbelkinの公式ホームページ上に小さく表示があり。Amazonで購入したがAmazon側には特にこの注意事項が無く見落とす。 USB-C端子経由の機能は制限されることがあり、すべてのUSB-C端子がUSB Type-C規格のすべての機能に対応が可能ではないことがありますので、ご注意ください。また、USB-C端子から外部モニターへの拡張表示に対応しない場合があります。 ドッキングステーション側でUSB Type Aが認識しなかった。ドライバを色々インストールしたが改善せず。 Anker PowerExpand Elite 13-in-1 Thunderbolt 3 Dock ドッキングステーション USB Type-Cのデバイス対応と記載あり USB Type-Cのデバイス経由でドッキングステーションに接続後、HDMI経由の外部モニター出力は出力されるが、USB Type-C経由の外部モニター出力が出力されない。 サポートに聞いたところ、USB Type-Cでドッキングステーションに接続するデバイスにおいて、USB Type-C経由の外部モニター出力はNGの模様。(ホームページ上に注意事項はどこにも書いていない。) Thunderbolt3対応のパソコンでは問題無かったので、大人しくThunderbolt3対応のデバイスを接続した方が良いのかもしれない。 結論 接続回りは非常にややこしくトラブルを引き起こしやすい。② thunderbolt3非対応(usb type-c)のPCを買い替えた方が良い気がしてきた…。 --- ### docker-composeでPostgreSQL構築 date: 2021-12-07 url: https://zatoima.github.io/postgres-docker-compose-install/ tags: Docker, PostgreSQL イメージ検索 公式のpostgresを使用する [ec2-user@bastin postgres-docker]$ docker search postgres NAME DESCRIPTION STARS OFFICIAL AUTOMATED postgres The PostgreSQL object-relational database sy… 10247 [OK] sameersbn/postgresql 161 [OK] postgrest/postgrest REST API for any Postgres database 51 centos/postgresql-96-centos7 PostgreSQL is an advanced Object-Relational … 45 wrouesnel/postgres_exporter Postgres metrics exporter for Prometheus. 30 arm32v7/postgres The PostgreSQL object-relational database sy… 29 prodrigestivill/postgres-backup-local Backup PostgresSQL to local filesystem with … 21 [OK] centos/postgresql-10-centos7 PostgreSQL is an advanced Object-Relational … 19 schickling/postgres-backup-s3 Backup PostgresSQL to S3 (supports periodic … 19 [OK] debezium/postgres PostgreSQL for use with Debezium change data… 18 [OK] arm64v8/postgres The PostgreSQL object-relational database sy… 17 centos/postgresql-94-centos7 PostgreSQL is an advanced Object-Relational … 16 postdock/postgres PostgreSQL server image, can work in master … 14 [OK] clkao/postgres-plv8 Docker image for running PLV8 1.4 on Postgre… 13 [OK] camptocamp/postgres Docker image for PostgreSQL including some e… 8 [OK] centos/postgresql-95-centos7 PostgreSQL is an advanced Object-Relational … 6 jgiannuzzi/postgres-bdr Docker image for PostgreSQL with BDR support 5 [OK] dcm4che/postgres-dcm4chee PostgreSQL for dcm4che-arc 5.x 5 [OK] centos/postgresql-12-centos7 PostgreSQL is an advanced Object-Relational … 4 blacklabelops/postgres Postgres Image for Atlassian Applications 4 [OK] tmaier/postgresql-client Run the PostgreSQL Client (psql) within a do… 2 [OK] ansibleplaybookbundle/postgresql-apb An APB which deploys RHSCL PostgreSQL 2 [OK] fredboat/postgres PostgreSQL 10.0 used in FredBoat's docker-co… 1 openshift/postgresql-92-centos7 DEPRECATED: A Centos7 based PostgreSQL v9.2 … 1 manageiq/postgresql Container with PostgreSQL and built on CentO… 0 [OK] タグ検索 特定のバージョンを指定する場合はタグを調べておく curl -s https://registry.hub.docker.com/v1/repositories/postgres/tags | jq -r '.[].name' docker-compose.ymlの準備 version: '3' services: postgres: image: postgres:latest restart: always environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres PGPASSWORD: postgres POSTGRES_DB: postgres TZ: "Asia/Tokyo" ports: - 5432:5432 volumes: - postgres:/var/lib/postgresql/data volumes: postgres: コンテナ作成 [ec2-user@bastin postgres-docker]$ docker-compose up -d Creating network "postgres-docker_default" with the default driver Creating volume "postgres-docker_postgres" with default driver Creating volume "postgres-docker_pgadmin" with default driver Pulling postgres (postgres:latest)... latest: Pulling from library/postgres e5ae68f74026: Already exists 7b8fcc7e1ad0: Pull complete 7527d03e2f77: Pull complete 80e55689f4d0: Pull complete 8a79eb6d69c9: Pull complete 397705f2d093: Pull complete de36ec4eb0a5: Pull complete 08d878a022c1: Pull complete 7677029670ff: Pull complete 1d24b3d9557e: Pull complete e085b018338c: Pull complete 063b09ff12e9: Pull complete a39fee215a44: Pull complete Digest: sha256:f76241d07218561e3d1a334eae6a5bf63c70b49f35ffecb7f020448e30e37390 Status: Downloaded newer image for postgres:latest Creating postgres-docker_postgres_1 ... done プロセス確認、接続 [ec2-user@bastin postgres-docker]$ ps -ef | grep postgres ec2-user 1193 29347 0 13:30 pts/1 00:00:00 grep --color=auto postgres libstor+ 31469 31428 0 13:28 ? 00:00:00 postgres libstor+ 31777 31469 0 13:28 ? 00:00:00 postgres: checkpointer libstor+ 31778 31469 0 13:28 ? 00:00:00 postgres: background writer libstor+ 31779 31469 0 13:28 ? 00:00:00 postgres: walwriter libstor+ 31780 31469 0 13:28 ? 00:00:00 postgres: autovacuum launcher libstor+ 31781 31469 0 13:28 ? 00:00:00 postgres: stats collector libstor+ 31782 31469 0 13:28 ? 00:00:00 postgres: logical replication launcher [ec2-user@bastin postgres-docker]$ [ec2-user@bastin postgres-docker]$ [ec2-user@bastin postgres-docker]$ psql -h localhost -p 5432 -d postgres -U postgres psql (11.12, server 14.1 (Debian 14.1-1.pgdg110+1)) WARNING: psql major version 11, server major version 14. Some psql features might not work. Type "help" for help. postgres=# select version(); version ----------------------------------------------------------------------------------------------------------------------------- PostgreSQL 14.1 (Debian 14.1-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit (1 row) postgres=# --- ### FIWAREに関する殴り書きメモ date: 2021-12-04 url: https://zatoima.github.io/fiware-about-memo/ tags: fiware FIWARE とは何か 分野横断的なデータ流通に主眼を置いたデータ管理基盤となり、スマートシティのための都市OSとも呼ばれる。 データ管理基盤と言われている通り、ただのインフラではなく、データマネジメントで必要と言われる多くの要素をコンポーネント単位に構築出来るようだ。 コアコンポーネントやデータカタログを扱うCKAN、データ可視化のためのGrafana等も使える模様。IoTデバイスからデータを受け取って可視化する機能もある。データのやり取りを行う中心はコンテキストブローカーであり、Pub/Sub的なデータのやり取りを行うことが出来る。担当するのはOrionというコンポーネントの模様。 結果的に都市に関する情報の生成、収集、公開、消費というのが出来る代物。都市を強調しているのは何故だろうか? 意義 都市OSに限らず、システム間連携は統一的な規格がないことが問題になりうる。また、米国はビックプラットフォーマーが存在し、データの囲い込みが行われつつある一方、欧州や日本等はオープンソースやFIWAREにおけるNGSI等の規格を使うことでエコシステムを作ろうとしているという見方もあるようだ。データを収集・蓄積するために規格を統一し、エコシステムを作って共栄していくことを目指す エコシステムという言葉:複数の企業が商品開発や事業活動などでパートナーシップを組み、互いの技術や資本を生かしながら、業界の枠や国境を超えて広く共存共栄していく仕組み FIWAREで実現出来ること 相互運用 データ流通 拡張性 データ活用やデータを扱う際にはDMBOKが参考になるが、DMBOKではデータガバナンスに関連する分野としてメタデータ管理やデータ連携、相互運用性、データモデリング、データアーキテクチャ等が記載されている。このあたりに対しても一部が有効らしい。様々なシステムと連携する場合は、どのようにデータを連携するか、フォーマットやファイル形式はどうするかのデータモデリング等を考える必要があるが、FIWAREではある程度決まったフレームワークで処理出来るように決まっている。 NGSIデータモデル オープンAPI 共通API NGSI(Next Generation Service Interfaces)という国際標準規格を使ってデータのやり取りを行うこととなるが、(珍しく?)日本によって策定されたようだ。(標準化自体は欧州の団体) データ連携のためのインターフェースとデータ格納時のデータモデルを定義している。データモデルでは「エンティティ(実体)」と、その属性情報であるコンテキスト情報から構成され、異なるアプリケーション同士でのデータ連携を行えるようにしている。データのセマンティクスは FIWARE Data Modelsとなる。 学ぶためには 正直調べてみてもよくわからないので、手っ取り早く学ぶために下記のチュートリアルをやったりした方が良さそう https://github.com/FIWARE/tutorials.Getting-Started/blob/master/README.ja.md 参考 官民データ活用共通プラットフォームの取り組み 誰でもできるスマートシティ向けOSS : FIWAREのはじめかた NGSI v2 まとめ - Qiita SIPサイバー/アーキテクチャ構築及び実証研究の成果公表 --- ### EC2にDockerをインストールしてFIWAREを動かす date: 2021-12-02 url: https://zatoima.github.io/aws-ec2-docker-fiware-install/ tags: AWS, Docker, Fiware 事前準備編 Dockerインストール sudo yum install -y docker sudo systemctl start docker sudo usermod -a -G docker ec2-user 自動起動を有効にする sudo systemctl enable docker FIWAREのインストール FIWAREの手順は下記の公式のgithubを参照 tutorials.Getting-Started/README.ja.md at master · FIWARE/tutorials.Getting-Started · GitHub Docker バージョン 18.03 以降を使用していることを確認 [ec2-user@bastin ~]$ docker version Client: Version: 20.10.7 API version: 1.41 Go version: go1.15.14 Git commit: f0df350 Built: Tue Sep 28 19:55:50 2021 OS/Arch: linux/amd64 Context: default Experimental: true [ec2-user@bastin ~]$ コンテナの起動 docker pull mongo:4.4 docker pull fiware/orion docker network create fiware_default MongoDB データベースを実行している Docker コンテナを 起動し、ネットワークに接続する docker run -d --name=mongo-db --network=fiware_default --expose=27017 mongo:4.4 --bind_ip_all fiware-orionのネットワーク接続 docker run -d --name fiware-orion --network=fiware_default -p 1026:1026 fiware/orion -dbhost mongo-db 設定のクリーンアップ(※必要な場合に実施する) docker stop fiware-orion docker rm fiware-orion docker stop mongo-db docker rm mongo-db docker network rm fiware_default httpリクエストの実施 バージョンの取得 curl -X GET 'http://localhost:1026/version' [ec2-user@bastin ~]$ curl -X GET 'http://localhost:1026/version' { "orion" : { "version" : "3.1.0-next", "uptime" : "0 d, 0 h, 1 m, 19 s", "git_hash" : "7bd1e43514539bd65caeb30d4e3319202e0f115b", "compile_time" : "Mon Jul 26 08:19:44 UTC 2021", "compiled_by" : "root", "compiled_in" : "dae1c5e3a7d9", "release_date" : "Mon Jul 26 08:19:44 UTC 2021", "machine" : "x86_64", "doc" : "https://fiware-orion.rtfd.io/", "libversions": { "boost": "1_66", "libcurl": "libcurl/7.61.1 OpenSSL/1.1.1g zlib/1.2.11 nghttp2/1.33.0", "libmicrohttpd": "0.9.70", "openssl": "1.1", "rapidjson": "1.1.0", "mongoc": "1.17.4", "bson": "1.17.4" } } } エンティティの作成 curl -sS http://localhost:1026/v2/entities \ -H 'Content-Type: application/json' \ -d @- <<EOF { "id": "living", "type": "Room", "temperature": {"value": 23, "type": "Float"} } EOF エンティティの確認 [ec2-user@bastin ~]$ curl -sS http://localhost:1026/v2/entities/living?type=Room -H 'Accept: application/json' | jq . { "id": "living", "type": "Room", "temperature": { "type": "Float", "value": 23, "metadata": {} } } エンティティの更新 curl -sS http://localhost:1026/v2/entities/living/attrs \ -H 'Content-Type: application/json' \ -X PATCH \ -d @- <<EOF { "temperature": { "value": 26.5, "type": "Float" } } EOF エンティティの確認 [ec2-user@bastin ~]$ curl -sS http://localhost:1026/v2/entities/living?type=Room -H 'Accept: application/json' | jq . { "id": "living", "type": "Room", "temperature": { "type": "Float", "value": 26.5, "metadata": {} } } [ec2-user@bastin ~]$ アトリビュートの更新 curl -sS http://localhost:1026/v2/entities/living/attrs/temperature/value \ -H 'Content-Type: text/plain' \ -X PUT \ -d 28.5 --- ### CloudTrailの料金が高い場合の対応 date: 2021-11-26 url: https://zatoima.github.io/aws-cloudtrail-cost-high/ tags: AWS ①AthenaでCloudTrailのAPI記録の傾向把握 eventsourceを特定して突出して多いサービスがないか確認 AthenaでCloudTrail の証跡を分析 | my opinion is my own SELECT awsregion, eventsource, eventname, COUNT(*) as cnt FROM cloudtrail_logs WHERE date>='2021/11/24' AND region = 'ap-northeast-1' GROUP BY awsregion, eventsource, eventname ORDER BY cnt DESC limit 10; 次は突出したeventsource、eventnameの深堀りを行う。UserIdenity要素にリクエスターの情報があるので、理由を特定する。 ②データイベントの配信、及びCloudTrail Insightsの配信の必要性の再検討、及び絞り込み 管理イベントの最初のコピーは無料だが、データイベントとInsightsの配信は有料なので注意をする。特にデータイベントのAPI数は多くなりやすい。 機能 料金 S3 に配信された管理イベント 管理イベントの最初のコピーは無料で配信されます。追加のコピー: 配信された 100,000 管理イベントあたり 2.00USD S3 に配信されたデータイベント 配信された 100,000 データイベントあたり 0.10USD CloudTrail Insights 分析された 100,000 イベントあたり 0.35USD 料金 - AWS CloudTrail | AWS 後はどのデータイベントを記録するかという絞り込みもイベントセレクタという機能で実施出来るので、不要なデータイベントを除外できるように設計する 証跡のデータイベントの記録 - AWS CloudTrail ③重複する CloudTrail 管理イベントをリージョン別に特定して削除する 下記を参照 CloudTrail のコストと使用量に予期しない増加があるのはなぜですか? 参考 20210119_AWSBlackbelt_CloudTrail.pdf --- ### CloudTrailのデータイベントはマネージメントコンソール上からは確認出来ない date: 2021-11-25 url: https://zatoima.github.io/aws-cloudtrail-dataevent-athena/ tags: AWS ハマったことのメモです。 データイベントとは? 20210119_AWSBlackbelt_CloudTrail.pdf ハマってしまったこと デフォルトではデータイベントは記録されないという事実は知っていたが、データイベントがマネージメントコンソール上に出力されないという事実を知らず、時間が掛かってしまった。(CloudTrailの情報は普段Athenaで検索するが、この時はマネージメントコンソールのイベント履歴から見ようとして出て来ず、なんで?と思ってた) マニュアルや公式のガイド的には下記の通り。 証跡での管理イベントの記録 - AWS CloudTrail CloudTrail の [イベント履歴] 機能では、管理イベントのみサポートされています。すべての管理イベントがイベント履歴に表示されるわけではありません。 CloudTrail のデータおよび管理イベントについて デフォルトでは、CloudTrail のデータイベントは無効になっています。追加料金をお支払いいただくことで、ログ記録を有効にできます。データイベントは、データプレーンオペレーションとも呼ばれ、しばしば大量の処理を含みます。データイベントは CloudTrail イベント履歴での表示はできません。 Athena を使用すると、Amazon S3 バケットに保存されているログファイルから、90 日を超えた CloudTrail のデータおよび管理イベントが表示できます 解決策 データイベントを見たい場合は、AthenaでCloudTrailを検索しましょう AthenaでCloudTrail の証跡を分析 | my opinion is my own --- ### VSCodeでデフォルトのシンタックスハイライトを設定する date: 2021-11-22 url: https://zatoima.github.io/other-vscode-syntax-default/ tags: VSCode 下の画像のようなプレーンテキストとか拡張子がついていないファイルに対してシンタックスを自動で設定したい。(下記の記事の通り、言語の自動検出機能が実装されていたりするので必要性は少なくなってきたけども。) VS Code に言語の自動検出機能が追加されました | DevelopersIO 「ユーザ設定」 - 「設定」でDefalut Languageを検索。ここで言語モードを設定する これで新規ファイルを作ったときに自動的に選択した言語がハイライトされる。 --- ### AthenaでCloudTrail の証跡を分析 date: 2021-11-18 url: https://zatoima.github.io/aws-cloudtrail-athena-analyze-query/ tags: AWS, Athena, CloudTrail CloudTrailのマネージメントコンソール上には「Athenaテーブルを作成」という機能がある。ここからAthenaで検索ができるようにDDLを用意してくれているが、これに落とし穴があった。S3上のファイル自体は日付ごとに格納されてパーティション化されているが、このDDL定義がパーティションに対応していない。余計なコストを発生させないために、Partition Projectionに対応したDDLを別途用意する必要がある。 Athenaでテーブルを作成する 【全リージョン対応】CloudTrailのログをAthenaのPartition Projectionなテーブルで作る | DevelopersIO Athenaのパーティションプロジェクションを利用してCloudTrailのログ検索をする - サーバーワークスエンジニアブログ drop table cloudtrail_logs; CREATE EXTERNAL TABLE cloudtrail_logs ( eventVersion STRING, userIdentity STRUCT< type: STRING, principalId: STRING, arn: STRING, accountId: STRING, invokedBy: STRING, accessKeyId: STRING, userName: STRING, sessionContext: STRUCT< attributes: STRUCT< mfaAuthenticated: STRING, creationDate: STRING>, sessionIssuer: STRUCT< type: STRING, principalId: STRING, arn: STRING, accountId: STRING, userName: STRING>>>, eventTime STRING, eventSource STRING, eventName STRING, awsRegion STRING, sourceIpAddress STRING, userAgent STRING, errorCode STRING, errorMessage STRING, requestParameters STRING, responseElements STRING, additionalEventData STRING, requestId STRING, eventId STRING, resources ARRAY<STRUCT< arn: STRING, accountId: STRING, type: STRING>>, eventType STRING, apiVersion STRING, readOnly STRING, recipientAccountId STRING, serviceEventDetails STRING, sharedEventID STRING, vpcEndpointId STRING ) COMMENT 'CloudTrail table for ${BucketName} bucket' PARTITIONED BY (region string, date string) ROW FORMAT SERDE 'com.amazon.emr.hive.serde.CloudTrailSerde' STORED AS INPUTFORMAT 'com.amazon.emr.cloudtrail.CloudTrailInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat' LOCATION 's3://z3-cloudtrail/AWSLogs/<Acclout ID>/CloudTrail/' TBLPROPERTIES ( 'projection.enabled' = 'true', 'projection.date.type' = 'date', 'projection.date.range' = 'NOW-1YEARS,NOW', 'projection.date.format' = 'yyyy/MM/dd', 'projection.date.interval' = '1', 'projection.date.interval.unit' = 'DAYS', 'projection.region.type' = 'enum', 'projection.region.values'='us-east-1,us-east-2,us-west-1,us-west-2,af-south-1,ap-east-1,ap-south-1,ap-northeast-2,ap-southeast-1,ap-southeast-2,ap-northeast-1,ca-central-1,eu-central-1,eu-west-1,eu-west-2,eu-south-1,eu-west-3,eu-north-1,me-south-1,sa-east-1', 'storage.location.template' = 's3://z3-cloudtrail/AWSLogs/<Acclout ID>/CloudTrail/${region}/${date}', 'classification'='cloudtrail', 'compressionType'='gzip', 'typeOfData'='file', 'classification'='cloudtrail' ); 分析クエリの発行 東京リージョンで2021年11月に発行されたAPIでeventsource、eventnameごとに集計する SELECT awsregion, eventsource, eventname, COUNT(*) as cnt FROM cloudtrail_logs WHERE date>='2021/11/01' AND region = 'ap-northeast-1' GROUP BY awsregion, eventsource, eventname ORDER BY cnt DESC limit 10; 実行時間も全量検索に比べて高速化している。スキャンしたデータも一部分のみ。 --- ### DMBOK勉強の殴り書きメモ(参照データとマスタデータ) date: 2021-11-15 url: https://zatoima.github.io/dmbok-memo-reference-data-master/ tags: DMBOK DMBOK勉強の殴り書きメモです。参照データとマスタデータについて。 参照データとマスタデータ DAMAホイールとは? データガバナンスを行うために必要な分野をまとめたもの マスタデータと参照データの定義 参照データ 他のデータ(マスタデータ含む)を特徴づける、関連づけるデータ 分類 注文状況:新規、処理中、キャンセル 外部情報 国コード:US、JPN、DE 外部情報との関連づけるために使われるデータ マスタデータ ビジネスに紐づくような主要業務の対象であるデータ 組織情報:従業員、ベンダー、顧客情報等 もの・サービス:商品、製品、中間品等 トランザクションデータ 企業の情報システムなどが扱うデータの種類の一つで、業務に伴って発生した出来事の詳細を記録したデータ 日々、追加・更新が発生 更新は各ユーザが行う 参照データやマスタデータは基本的に管理者が行うもの スタースキーマでいうところのディメンション表が参照データ、マスタデータにあたり、ファクト表がトランザクションデータと思っている。(図の参照元) マスターデータ管理の意義、目的 組織のデータ要件のため 完全で最新で一貫性がある信頼出来るデータで分析しなければ意味がない データの品質管理 データ不整合や不良、欠落を避ける データ統合のコスト管理 マスターデータがない場合のデータソース統合はコストが掛かる リスクの低減、削減 データ共有アーキテクチャの簡素化、リスク、並びにコストが下がる マスターデータ管理の指針 共有データ:参照データとマスターデータは組織全体で共有できるように管理 データ所有権:参照データとマスタデータは組織に属して特定アプリケーションや部門には属さないようにする 品質:データ品質の監視とガバナンスを効かす スチュワード:業務データの生成元のデータスチュワードは参照データの品質を管理して保証するために責務を負う 変更管理 変更時にはプロセスを経て変更する。承認フロー、及び関係者への伝達、配信等。 MDM要件の評価に必要なもの どの役割、組織、場所、物が繰り返し参照されているか 人、組織、場所、物を記述するためにどのデータが使われているか どのようにデータが定義され構造化されているか。これにはデータの粒度も含まれる どこでデータが作成/収集され、保存され、利用可能になり、アクセスされるか データが組織内のシステムを移動する際にどのように変化するか 誰がどのような目的でデータを利用するのか データとそのソース品質と信頼性を理解するためにどのような基準が使われるか --- ### DMBOK勉強の殴り書きメモ(データガバナンスとデータマネージメント) date: 2021-11-09 url: https://zatoima.github.io/dmbok-memo-data-governance-data-management/ tags: DMBOK DMBOK勉強の殴り書きメモです。データガバナンスとデータマネージメント編を中心に。 DAMAホイールとは? データガバナンスを行うために必要な分野をまとめたもの データガバナンスとは? 定義:データ資産の管理に対して職務権限を通し統制(コントロール)すること 適切な組織人員の配置 組織体制の構築 データスチュワード制 重要な領域をインハウス化する一方定型業務はアウトソース等 経営層のコミットが必要 データマネジメント活動の共有 スモールスタートが望ましい 活動領域の適宜共有 ゴール:組織が自身のデータを資産として管理する データマネジメントに関する原則、ポリシー、手続き、評価指標、ツール、責任について定義、承認、伝達、実施する ポリシーの遵守、データの利用、管理活動を監視して導く あくまでもデータガバナンスは手段なので目的にならないように注意する。管理のための管理等 データガバナンスで目指すべき方向性 データは企業資産として管理すべき データマネージメントのベストプラクティスを組織全体に対して奨励すべき 企業データ戦略はビジネス戦略全体に直接呼応すべき データマネジメントプロセスは継続的に改善 ISO 55000/55001 資産管理に関係する国際基準 組織の資産(アセット)をライフサイクルを通じて、コスト、リスク、パフォーマンスのバランスを保ちながら、最大の可用性と収益性を確保するため 一般社団法人 日本アセットマネジメント協会(JAAM)|ISO 55000シリーズとは? https://www.ja-am.or.jp/iso55000s アセットマネジメントシステム(AMS)認証 (ISO 55001) | 公益財団法人 日本適合性認定協会 https://www.jab.or.jp/iso/iso_55001/ データ評価のアプローチ データの取得と保存のコスト データが失われた場合のデータ復旧コスト データの販売目的の明確化 データ使用による期待収益 データ管理の目的 データを効果的に使用して企業に価値を付加出来るようにすること リスク軽減 プロセス改善 規制遵守 データ品質改善 メタデータ管理 開発プロジェクトの効率性 ベンダー管理 データスチュワード 役割 組織のデータ資産の品質と使用に責任を持つように任命されたビジネス上の役割 職務の種類例 メタデータの作成と管理 ルールと標準の文書 データ品質の問題管理 データガバナンス運営アクティビティの実施 色々なデータスチュワードの種類が存在する チーフ・データスチュワード:エグゼクティブスポンサー 執行役データスチュワード:データガバナンス評議会に所属する上級管理者 エンタープライズ・データスチュワード:業務機能全体にわたるデータドメイン(領域) 業務データスチュワード:ステークホルダと協力してデータを定義し統制 データオーナー:業務データスチュワードでもあり、自分の担当分野内のデータに関する意思決定の承認権限 ITデータスチュワード:ITのプロフェッショナルであり、データ統合スペシャリスト、データベース管理者、ビジネスインテリジェンス・スペシャリスト、データ品質アナリスト、メタデータ管理者など各知識領域で機能 調整役データスチュワード:業務データスチュワードとITデータスチュワードのチームの代表として、チーム間や執行役データスチュワードとの議論に臨む データガバナンスとは? データ改善の継続的なプロセス 様々な組織モデルがあり得る データ資産の管理に対する権限と制御の行使 規制やコンプライアンス要件を満たしていることを監視、確認する データガバナンスを実行していくことの責任は? データ管理コミュニティの全員で実行していくこと データシチュワード CEO/CIO/CDO 業務関係者 データ資産評価 組織におけるデータの経済的価値を理解し測定するプロセス データを利用することの経済的利益がデータの取得と保管のコストや使用に関するリスク管理のコストを上回る場合に、価値がもたらされる。 データガバナンスの価値を届けるアプローチ例 データ管理のイントラWebサイトの保守 定期的なニュースレターの発行 フォーラムやコミュニティへの参加促進 関係者やオーディエンス向けにエレベーターピッチの作成 データ管理のイントラWebサイトに掲載する内容 データガバナンス組織の連絡先 データ管理や既存のデータ管理の問題に対してのエグゼクティブメッセージ データスチュワードチームのプロファイル データ管理の問題点を報告する仕組み、メールリンク データ標準ガイドライン 定期的にレビューと更新が必要 データガバナンス運営委員会 データガバナンス活動の監視とサポートを担当する主要かつ最高の機関 ISO 3166 国際標準化機構 (ISO) が国名およびそれに準ずる区域、都道府県や州といった地域のために割り振った地理情報の符号化 ISO 3166 - Wikipedia https://ja.wikipedia.org/wiki/ISO_3166 データ管理の目標 データ資産の取得、保存、保護、整合性の確保 データと情報の品質の確保 利害関係者データのプライバシーと機密性の確保 データガバナンス戦略 IT戦略だけではなく全体的な事業戦略に関連させる必要がある オペレーションフレームワークと結果責任 導入ロードマップ 運用計画 データガバナンスの意義、ビジョン、使命、原則を示すもの データマネジメント・プロジェクトの支援 内部SDLC、サービス展開管理、ITIL、PMOプロセスへの関与、対応が必要 組織との連携ポイントの策定 データガバナンス業務のために連携する組織との協業体制を検討 調達と契約 予算、資金調達 規制遵守 SDLC/開発フレームワーク データマネジメント成熟度 現在のデータマネジメント遂行能力と遂行範囲を測定する 変革能力 協調体制の準備状況 事業との整合性 --- ### VSCodeにお気に入りフォントを設定する date: 2021-11-06 url: https://zatoima.github.io/vscode-font-favorite/ tags: その他, VSCode mzyy94/RictyDiminished-for-Powerline: Ricty Diminished with Powerline patched --- fonts for programming RictyDiminished-Regular.ttf RictyDiminished-Oblique.ttf このあたりをインストールして、vscodeの設定のフォントにて“Ricty Diminished”に設定 --- ### PythonのPyArrorwを使用してCSVをParquetに変換、及び確認 date: 2021-11-03 url: https://zatoima.github.io/python-pyarrow-convert-csv-to-parquet-pandas/ tags: Python pandasでparquetを扱えることを知った テスト用CSVの作成 cat << EOF > testdata.csv 1,test1,ゎぶばあちあぬナクバ 2,test2,がマうひバぴじクハぺ 3,test3,スみでてゥあッあけげ EOF pyarrowのインストール pip install pyarrow csvからparquetへの変換 import pandas as pd import pyarrow as pa import pyarrow.parquet as pq #csvからparquetへの変換 df = pd.read_csv('./testdata.csv') table = pa.Table.from_pandas(df) pq.write_table(table, './testdata.parquet') parquetの内容確認 #parquetの内容確認 load_df_pq = pd.read_parquet("./testdata.parquet") print(load_df_pq.info()) print(load_df_pq) AWSのs3 selectでもParquetを簡単に見れて便利 --- ### parquet-toolsのインストール、及び操作方法のメモ date: 2021-11-02 url: https://zatoima.github.io/parquet-tools-how-to-install-and-operate/ tags: その他 インストール maven、javaのインストール確認 [ec2-user@bastin ~]$ mvn -version Apache Maven 3.5.2 (138edd61fd100ec658bfa2d307c43b76940a5d7d; 2017-10-18T07:58:13Z) Maven home: /usr/share/apache-maven Java version: 1.8.0_302, vendor: Red Hat, Inc. Java home: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.302.b08-0.amzn2.0.1.x86_64/jre Default locale: en_US, platform encoding: UTF-8 OS name: "linux", version: "4.14.248-189.473.amzn2.x86_64", arch: "amd64", family: "unix" 資材のインストール [ec2-user@bastin ~]$ mkdir parquet [ec2-user@bastin ~]$ cd parquet/ [ec2-user@bastin parquet]$ git clone https://github.com/apache/parquet-mr.git Cloning into 'parquet-mr'... remote: Enumerating objects: 68629, done. remote: Counting objects: 100% (1532/1532), done. remote: Compressing objects: 100% (835/835), done. remote: Total 68629 (delta 595), reused 1163 (delta 394), pack-reused 67097 Receiving objects: 100% (68629/68629), 17.45 MiB | 18.62 MiB/s, done. Resolving deltas: 100% (40079/40079), done. [ec2-user@bastin parquet]$ cd ./parquet-mr/parquet-tools/ -bash: cd: ./parquet-mr/parquet-tools/: No such file or directory [ec2-user@bastin parquet]$ cd ./parquet-mr/ [ec2-user@bastin parquet-mr]$ ls -l total 156 -rwxrwxr-x 1 ec2-user ec2-user 2178 Oct 20 10:12 changelog.sh -rw-rw-r-- 1 ec2-user ec2-user 84314 Oct 20 10:12 CHANGES.md drwxrwxr-x 2 ec2-user ec2-user 209 Oct 20 10:12 dev drwxrwxr-x 3 ec2-user ec2-user 26 Oct 20 10:12 doc -rw-rw-r-- 1 ec2-user ec2-user 11626 Oct 20 10:12 LICENSE -rw-rw-r-- 1 ec2-user ec2-user 3569 Oct 20 10:12 NOTICE drwxrwxr-x 3 ec2-user ec2-user 32 Oct 20 10:12 parquet-arrow drwxrwxr-x 3 ec2-user ec2-user 69 Oct 20 10:12 parquet-avro drwxrwxr-x 3 ec2-user ec2-user 63 Oct 20 10:12 parquet-benchmarks -rw-rw-r-- 1 ec2-user ec2-user 9486 Oct 20 10:12 parquet_cascading.md drwxrwxr-x 3 ec2-user ec2-user 49 Oct 20 10:12 parquet-cli drwxrwxr-x 3 ec2-user ec2-user 52 Oct 20 10:12 parquet-column drwxrwxr-x 3 ec2-user ec2-user 52 Oct 20 10:12 parquet-common drwxrwxr-x 3 ec2-user ec2-user 52 Oct 20 10:12 parquet-encoding drwxrwxr-x 3 ec2-user ec2-user 32 Oct 20 10:12 parquet-format-structures drwxrwxr-x 3 ec2-user ec2-user 52 Oct 20 10:12 parquet-generator drwxrwxr-x 3 ec2-user ec2-user 69 Oct 20 10:12 parquet-hadoop drwxrwxr-x 3 ec2-user ec2-user 46 Oct 20 10:12 parquet-hadoop-bundle drwxrwxr-x 3 ec2-user ec2-user 49 Oct 20 10:12 parquet-jackson drwxrwxr-x 3 ec2-user ec2-user 52 Oct 20 10:12 parquet-pig drwxrwxr-x 3 ec2-user ec2-user 32 Oct 20 10:12 parquet-pig-bundle drwxrwxr-x 3 ec2-user ec2-user 69 Oct 20 10:12 parquet-protobuf drwxrwxr-x 3 ec2-user ec2-user 32 Oct 20 10:12 parquet-scala drwxrwxr-x 3 ec2-user ec2-user 69 Oct 20 10:12 parquet-thrift -rw-rw-r-- 1 ec2-user ec2-user 23053 Oct 20 10:12 pom.xml -rw-rw-r-- 1 ec2-user ec2-user 3049 Oct 20 10:12 PoweredBy.md -rw-rw-r-- 1 ec2-user ec2-user 10418 Oct 20 10:12 README.md drwxrwxr-x 2 ec2-user ec2-user 25 Oct 20 10:12 src [ec2-user@bastin parquet-mr]$ git checkout apache-parquet-1.10.1 Note: switching to 'apache-parquet-1.10.1'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by switching back to a branch. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -c with the switch command. Example: git switch -c <new-branch-name> Or undo this operation with: git switch - Turn off this advice by setting config variable advice.detachedHead to false HEAD is now at a89df8f99 [maven-release-plugin] prepare release apache-parquet-1.10.1 ビルド [ec2-user@bastin parquet-mr]$ cd parquet-tools/ [ec2-user@bastin parquet-tools]$ mvn clean package -Plocal [INFO] Scanning for projects... [INFO] [INFO] ----------------------------------------------------------- ~中略~ [WARNING] See http://docs.codehaus.org/display/MAVENUSER/Shade+Plugin [INFO] Replacing original artifact with shaded artifact. [INFO] Replacing /home/ec2-user/parquet/parquet-mr/parquet-tools/target/parquet-tools-1.10.1.jar with /home/ec2-user/parquet/parquet-mr/parquet-tools/target/parquet-tools-1.10.1-shaded.jar [INFO] Dependency-reduced POM written at: /home/ec2-user/parquet/parquet-mr/parquet-tools/dependency-reduced-pom.xml [INFO] Dependency-reduced POM written at: /home/ec2-user/parquet/parquet-mr/parquet-tools/dependency-reduced-pom.xml [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 22.757 s [INFO] Finished at: 2021-10-20T01:13:55Z [INFO] Final Memory: 35M/377M [INFO] ------------------------------------------------------------------------ [ec2-user@bastin parquet-tools]$ [ec2-user@bastin parquet-tools]$ ls -l total 20 -rw-rw-r-- 1 ec2-user ec2-user 3172 Oct 20 10:13 dependency-reduced-pom.xml -rw-rw-r-- 1 ec2-user ec2-user 4306 Oct 20 10:12 pom.xml -rw-rw-r-- 1 ec2-user ec2-user 2354 Oct 20 10:12 README.md -rw-rw-r-- 1 ec2-user ec2-user 979 Oct 20 10:12 REVIEWERS.md drwxrwxr-x 4 ec2-user ec2-user 30 Oct 20 10:12 src drwxrwxr-x 10 ec2-user ec2-user 304 Oct 20 10:13 target [ec2-user@bastin parquet-tools]$ cd target/ [ec2-user@bastin target]$ ls -l total 42332 drwxrwxr-x 4 ec2-user ec2-user 33 Oct 20 10:13 classes drwxrwxr-x 3 ec2-user ec2-user 25 Oct 20 10:13 generated-sources drwxrwxr-x 3 ec2-user ec2-user 30 Oct 20 10:13 generated-test-sources drwxrwxr-x 2 ec2-user ec2-user 28 Oct 20 10:13 maven-archiver drwxrwxr-x 3 ec2-user ec2-user 35 Oct 20 10:13 maven-status -rw-rw-r-- 1 ec2-user ec2-user 81190 Oct 20 10:13 original-parquet-tools-1.10.1.jar -rw-rw-r-- 1 ec2-user ec2-user 43242062 Oct 20 10:13 parquet-tools-1.10.1.jar -rw-rw-r-- 1 ec2-user ec2-user 11045 Oct 20 10:13 parquet-tools-1.10.1-tests.jar -rw-rw-r-- 1 ec2-user ec2-user 3124 Oct 20 10:13 rat.txt drwxrwxr-x 2 ec2-user ec2-user 6 Oct 20 10:13 surefire drwxrwxr-x 2 ec2-user ec2-user 4096 Oct 20 10:13 surefire-reports drwxrwxr-x 3 ec2-user ec2-user 17 Oct 20 10:13 test-classes [ec2-user@bastin target]$ parquet-toolsの操作方法 中身の確認 [ec2-user@bastin pyarrow]$ java -jar $HOME/parquet/parquet-mr/parquet-tools/target/parquet-tools-1.10.1.jar cat testdata.parquet id = 1 name = test1 comment = ゎ id = 2 name = test2 comment = が id = 3 name = test3 comment = ス メタ情報の確認 [ec2-user@bastin pyarrow]$ java -jar $HOME/parquet/parquet-mr/parquet-tools/target/parquet-tools-1.10.1.jar meta testdata.parquet file: file:/home/ec2-user/pyarrow/testdata.parquet creator: parquet-cpp-arrow version 5.0.0 extra: pandas = {"index_columns": [{"kind": "range", "name": null, "start": 0, "stop": 3, "step": 1}], "column_indexes": [{"name": null, "field_name": null, "pandas_type": "unicode", "numpy_type": "object", "metadata": {"encoding": "UTF-8"}}], "columns": [{"name": "id", "field_name": "id", "pandas_type": "int64", "numpy_type": "int64", "metadata": null}, {"name": "name", "field_name": "name", "pandas_type": "unicode", "numpy_type": "object", "metadata": null}, {"name": "comment", "field_name": "comment", "pandas_type": "unicode", "numpy_type": "object", "metadata": null}], "creator": {"library": "pyarrow", "version": "5.0.0"}, "pandas_version": "1.0.5"} extra: ARROW:schema = /////5ADAAAQAAAAAAAKAA4ABgAFAAgACgAAAAABBAAQAAAAAAAKAAwAAAAEAAgACgAAALwCAAAEAAAAAQAAAAwAAAAIAAwABAAIAAgAAAAIAAAAEAAAAAYAAABwYW5kYXMAAIUCAAB7ImluZGV4X2NvbHVtbnMiOiBbeyJraW5kIjogInJhbmdlIiwgIm5hbWUiOiBudWxsLCAic3RhcnQiOiAwLCAic3RvcCI6IDMsICJzdGVwIjogMX1dLCAiY29sdW1uX2luZGV4ZXMiOiBbeyJuYW1lIjogbnVsbCwgImZpZWxkX25hbWUiOiBudWxsLCAicGFuZGFzX3R5cGUiOiAidW5pY29kZSIsICJudW1weV90eXBlIjogIm9iamVjdCIsICJtZXRhZGF0YSI6IHsiZW5jb2RpbmciOiAiVVRGLTgifX1dLCAiY29sdW1ucyI6IFt7Im5hbWUiOiAiaWQiLCAiZmllbGRfbmFtZSI6ICJpZCIsICJwYW5kYXNfdHlwZSI6ICJpbnQ2NCIsICJudW1weV90eXBlIjogImludDY0IiwgIm1ldGFkYXRhIjogbnVsbH0sIHsibmFtZSI6ICJuYW1lIiwgImZpZWxkX25hbWUiOiAibmFtZSIsICJwYW5kYXNfdHlwZSI6ICJ1bmljb2RlIiwgIm51bXB5X3R5cGUiOiAib2JqZWN0IiwgIm1ldGFkYXRhIjogbnVsbH0sIHsibmFtZSI6ICJjb21tZW50IiwgImZpZWxkX25hbWUiOiAiY29tbWVudCIsICJwYW5kYXNfdHlwZSI6ICJ1bmljb2RlIiwgIm51bXB5X3R5cGUiOiAib2JqZWN0IiwgIm1ldGFkYXRhIjogbnVsbH1dLCAiY3JlYXRvciI6IHsibGlicmFyeSI6ICJweWFycm93IiwgInZlcnNpb24iOiAiNS4wLjAifSwgInBhbmRhc192ZXJzaW9uIjogIjEuMC41In0AAAADAAAAcAAAADAAAAAEAAAArP///wAAAQUQAAAAGAAAAAQAAAAAAAAABwAAAGNvbW1lbnQA2P///9T///8AAAEFEAAAABwAAAAEAAAAAAAAAAQAAABuYW1lAAAAAAQABAAEAAAAEAAUAAgABgAHAAwAAAAQABAAAAAAAAECEAAAABwAAAAEAAAAAAAAAAIAAABpZAAACAAMAAgABwAIAAAAAAAAAUAAAAA= file schema: schema -------------------------------------------------------------------------------- id: OPTIONAL INT64 R:0 D:1 name: OPTIONAL BINARY O:UTF8 R:0 D:1 comment: OPTIONAL BINARY O:UTF8 R:0 D:1 row group 1: RC:3 TS:271 OFFSET:4 -------------------------------------------------------------------------------- id: INT64 UNCOMPRESSED DO:4 FPO:42 SZ:109/109/1.00 VC:3 ENC:PLAIN_DICTIONARY,RLE,PLAIN ST:[min: 1, max: 3, num_nulls: 0] name: BINARY UNCOMPRESSED DO:205 FPO:246 SZ:86/86/1.00 VC:3 ENC:PLAIN_DICTIONARY,RLE,PLAIN ST:[min: test1, max: test3, num_nulls: 0] comment: BINARY UNCOMPRESSED DO:361 FPO:396 SZ:76/76/1.00 VC:3 ENC:PLAIN_DICTIONARY,RLE,PLAIN ST:[min: が, max: ス, num_nulls: 0] [ec2-user@bastin pyarrow]$ スキーマ情報の確認 [ec2-user@bastin pyarrow]$ java -jar $HOME/parquet/parquet-mr/parquet-tools/target/parquet-tools-1.10.1.jar schema testdata.parquet message schema { optional int64 id; optional binary name (UTF8); optional binary comment (UTF8); } ダンプ [ec2-user@bastin pyarrow]$ java -jar $HOME/parquet/parquet-mr/parquet-tools/target/parquet-tools-1.10.1.jar dump testdata.parquet row group 0 -------------------------------------------------------------------------------- id: INT64 UNCOMPRESSED DO:4 FPO:42 SZ:109/109/1.00 VC:3 ENC:RLE, [more]... name: BINARY UNCOMPRESSED DO:205 FPO:246 SZ:86/86/1.00 VC:3 ENC:RL [more]... comment: BINARY UNCOMPRESSED DO:361 FPO:396 SZ:76/76/1.00 VC:3 ENC:RL [more]... id TV=3 RL=0 DL=1 DS: 3 DE:PLAIN_DICTIONARY ---------------------------------------------------------------------------- page 0: DLE:RLE RLE:RLE VLE:PLAIN_DICTIONARY S [more]... VC:3 name TV=3 RL=0 DL=1 DS: 3 DE:PLAIN_DICTIONARY ---------------------------------------------------------------------------- page 0: DLE:RLE RLE:RLE VLE:PLAIN_DICTIONARY S [more]... VC:3 comment TV=3 RL=0 DL=1 DS: 3 DE:PLAIN_DICTIONARY ---------------------------------------------------------------------------- page 0: DLE:RLE RLE:RLE VLE:PLAIN_DICTIONARY S [more]... VC:3 INT64 id -------------------------------------------------------------------------------- *** row group 1 of 1, values 1 to 3 *** value 1: R:0 D:1 V:1 value 2: R:0 D:1 V:2 value 3: R:0 D:1 V:3 BINARY name -------------------------------------------------------------------------------- *** row group 1 of 1, values 1 to 3 *** value 1: R:0 D:1 V:test1 value 2: R:0 D:1 V:test2 value 3: R:0 D:1 V:test3 BINARY comment -------------------------------------------------------------------------------- *** row group 1 of 1, values 1 to 3 *** value 1: R:0 D:1 V:ゎ value 2: R:0 D:1 V:が value 3: R:0 D:1 V:ス [ec2-user@bastin pyarrow]$ 行数の確認 [ec2-user@bastin pyarrow]$ java -jar $HOME/parquet/parquet-mr/parquet-tools/target/parquet-tools-1.10.1.jar rowcount testdata.parquet Total RowCount: 3 サイズ確認 [ec2-user@bastin pyarrow]$ java -jar $HOME/parquet/parquet-mr/parquet-tools/target/parquet-tools-1.10.1.jar size testdata.parquet Total Size: 271 bytes マージ 仮にこんな感じにパーティションごとに分かれているparquetがあったとして、、、 [ec2-user@bastin pyarrow]$ find pq -type f pq/id=1/ad317ec807644ad98298860e7fb9d041.snappy.parquet pq/id=2/ad317ec807644ad98298860e7fb9d041.snappy.parquet pq/id=3/ad317ec807644ad98298860e7fb9d041.snappy.parquet 一つのファイルには1行程度のサイズしかないとする(こんな分割方法はありえないけども・・・) [ec2-user@bastin pyarrow]$ java -jar $HOME/parquet/parquet-mr/parquet-tools/target/parquet-tools-1.10.1.jar cat pq/id=1/ad317ec807644ad98298860e7fb9d041.snappy.parquet name = test1 comment = ゎぶばあちあぬナクバ 下記でマージ [ec2-user@bastin pyarrow]$ java -jar $HOME/parquet/parquet-mr/parquet-tools/target/parquet-tools-1.10.1.jar merge pq/id=1/ad317ec807644ad98298860e7fb9d041.snappy.parquet pq/id=2/ad317ec807644ad98298860e7fb9d041.snappy.parquet pq/id=3/ad317ec807644ad98298860e7fb9d041.snappy.parquet merge.pq Warning: file pq/id=1/ad317ec807644ad98298860e7fb9d041.snappy.parquet is too small, length: 1899 Warning: file pq/id=2/ad317ec807644ad98298860e7fb9d041.snappy.parquet is too small, length: 1899 Warning: file pq/id=3/ad317ec807644ad98298860e7fb9d041.snappy.parquet is too small, length: 1899 Warning: you merged too small files. Although the size of the merged file is bigger, it STILL contains small row groups, thus you don't have the advantage of big row groups, which usually leads to bad query performance! catで確認 [ec2-user@bastin pyarrow]$ java -jar $HOME/parquet/parquet-mr/parquet-tools/target/parquet-tools-1.10.1.jar cat merge.pq name = test1 comment = ゎぶばあちあぬナクバ name = test2 comment = がマうひバぴじクハぺ name = test3 comment = スみでてゥあッあけげ ヘルプ [ec2-user@bastin pyarrow]$ java -jar $HOME/parquet/parquet-mr/parquet-tools/target/parquet-tools-1.10.1.jar help Unknown command: help parquet-tools cat: Prints the content of a Parquet file. The output contains only the data, no metadata is displayed usage: parquet-tools cat [option...] <input> where option is one of: --debug Enable debug output -h,--help Show this help string -j,--json Show records in JSON format. --no-color Disable color output even if supported where <input> is the parquet file to print to stdout parquet-tools head: Prints the first n record of the Parquet file usage: parquet-tools head [option...] <input> where option is one of: --debug Enable debug output -h,--help Show this help string -n,--records <arg> The number of records to show (default: 5) --no-color Disable color output even if supported where <input> is the parquet file to print to stdout parquet-tools schema: Prints the schema of Parquet file(s) usage: parquet-tools schema [option...] <input> where option is one of: -d,--detailed Show detailed information about the schema. --debug Enable debug output -h,--help Show this help string --no-color Disable color output even if supported where <input> is the parquet file containing the schema to show parquet-tools meta: Prints the metadata of Parquet file(s) usage: parquet-tools meta [option...] <input> where option is one of: --debug Enable debug output -h,--help Show this help string --no-color Disable color output even if supported where <input> is the parquet file to print to stdout parquet-tools dump: Prints the content and metadata of a Parquet file usage: parquet-tools dump [option...] <input> where option is one of: -c,--column <arg> Dump only the given column, can be specified more than once -d,--disable-data Do not dump column data --debug Enable debug output -h,--help Show this help string -m,--disable-meta Do not dump row group and page metadata -n,--disable-crop Do not crop the output based on console width --no-color Disable color output even if supported where <input> is the parquet file to print to stdout parquet-tools merge: Merges multiple Parquet files into one. The command doesn't merge row groups, just places one after the other. When used to merge many small files, the resulting file will still contain small row groups, which usually leads to bad query performance. usage: parquet-tools merge [option...] <input> [<input> ...] <output> where option is one of: --debug Enable debug output -h,--help Show this help string --no-color Disable color output even if supported where <input> is the source parquet files/directory to be merged <output> is the destination parquet file parquet-tools rowcount: Prints the count of rows in Parquet file(s) usage: parquet-tools rowcount [option...] <input> where option is one of: -d,--detailed Detailed rowcount of each matching file --debug Enable debug output -h,--help Show this help string --no-color Disable color output even if supported where <input> is the parquet file to count rows to stdout parquet-tools size: Prints the size of Parquet file(s) usage: parquet-tools size [option...] <input> where option is one of: -d,--detailed Detailed size of each matching file --debug Enable debug output -h,--help Show this help string --no-color Disable color output even if supported -p,--pretty Pretty size -u,--uncompressed Uncompressed size where <input> is the parquet file to get size & human readable size to stdout --- ### DELL XPS 8900にて電源が入らない状況から回復した方法 date: 2021-10-31 url: https://zatoima.github.io/dell-xps-8900-recovery-lost-power/ tags: その他 電源ボタンあたりに埃が溜まって接触が悪いのか、と思って分解して掃除したけど改善せず。ググって出てきたこちらの記事で見事に治りました。電源ボタンを10秒以上押し続けて放電させることで再度電源が点くようになった。公式さん、ありがとう。 Dell PCの電源が入らない、またはWindowsが起動しない | Dell 日本 パソコンの電源が入らない場合の問題改善方法 - YouTube --- ### ThinkPad ワイヤレス キーボードII でトラックポイントの調整をする方法 date: 2021-10-29 url: https://zatoima.github.io/thinkpad-wireless-keyboard-2-track-point-setting/ tags: その他 以前はデバイスマネージャーから設定した記憶があったが、ユーティリティをインストールする必要があるようだ。 設定手順 ThinkPad トラックポイント キーボード II ソフトウェアを下記からダウンロードする。 https://support.lenovo.com/jp/ja/downloads/ds543713-thinkpad-trackpoint-keyboard-ii-software-for-windows-7-windows-10 exeファイル実行後、適当にインストールして、キーボードのプロパティから変更する --- ### Redshift SpectrumからGlue Data Catalogのテーブルを参照する date: 2021-10-28 url: https://zatoima.github.io/aws-redshift-spectrum-select-data-catalog/ tags: AWS, Redshift Athena側で作ったGlue Data Catalog側のデータベース名、テーブル名の前提は下記記事。 AthenaでParquetファイルのデータカタログ作成 | my opinion is my own データベース名:catalogtest テーブル名:testdata 外部スキーマ名:external_schema Redshift側で外部スキーマを定義 データカタログ側にデータベース、テーブルがある状態であれば外部スキーマ定義を行うだけで良い。S3やGlueの権限をiam_roleとしてRedshiftにアタッチしておく必要がある。 drop schema external_schema; create external schema external_schema from data catalog database 'catalogtest' iam_role 'arn:aws:iam::xxxxxxx:role/myRedshiftRole' create external database if not exists; mydb=# create external schema external_schema from data catalog mydb-# database 'catalogtest' mydb-# iam_role 'arn:aws:iam::xxxxxxx:role/myRedshiftRole' mydb-# create external database if not exists; INFO: External database "catalogtest" already exists CREATE SCHEMA スキーマの確認 mydb=# select schemaname, databasename from svv_external_schemas where schemaname='external_schema'; schemaname | databasename -----------------+-------------- external_schema | catalogtest (1 row) mydb=# select schemaname, tablename, location from SVV_EXTERNAL_TABLES where schemaname='external_schema'; schemaname | tablename | location -----------------+-----------+-------------------- external_schema | testdata | s3://202110test/pq (1 row) mydb=# select * from SVV_EXTERNAL_COLUMNS where tablename = 'testdata'; schemaname | tablename | columnname | external_type | columnnum | part_key | is_nullable -----------------+-----------+------------+---------------+-----------+----------+------------- external_schema | testdata | id | string | 1 | 0 | external_schema | testdata | name | string | 2 | 0 | external_schema | testdata | comment | string | 3 | 0 | (3 rows) クエリを行う mydb=# select name,comment from external_schema.testdata; name | comment -------+---------------------- test1 | ゎぶばあちあぬナクバ test2 | がマうひバぴじクハぺ test3 | スみでてゥあッあけげ (3 rows) --- ### PostgreSQLでデータベース全体の論理バックアップから個別テーブルをリストアする date: 2021-10-27 url: https://zatoima.github.io/postgresql-database-logical-backup-restore-table/ tags: PostgreSQL コマンド pg_dumpによりデータベース全体をバックアップ pg_dump -Fc -v -h auroratest1.cluster-xxxxxxx.ap-northeast-1.rds.amazonaws.com -U postgres pgbench > pgbench.dump pg_restoreにより"特定テーブルのみ"をリストア psql -h auroratest1.cluster-xxxxxxx.ap-northeast-1.rds.amazonaws.com -d postgres -U postgres -c "create database pgbench_restore" pg_restore -v -h auroratest1.cluster-xxxxxxx.ap-northeast-1.rds.amazonaws.com -U postgres -d pgbench_restore -t pgbench_accounts pgbench.dump 実行ログ バックアップ [ec2-user@bastin ~]$ pg_dump -Fc -v -h auroratest1.cluster-xxxxxxx.ap-northeast-1.rds.amazonaws.com -U postgres pgbench > pgbench.dump pg_dump: last built-in OID is 16383 pg_dump: reading extensions pg_dump: identifying extension members pg_dump: reading schemas pg_dump: reading user-defined tables pg_dump: reading user-defined functions pg_dump: reading user-defined types pg_dump: reading procedural languages pg_dump: reading user-defined aggregate functions pg_dump: reading user-defined operators pg_dump: reading user-defined access methods pg_dump: reading user-defined operator classes pg_dump: reading user-defined operator families pg_dump: reading user-defined text search parsers pg_dump: reading user-defined text search templates pg_dump: reading user-defined text search dictionaries pg_dump: reading user-defined text search configurations pg_dump: reading user-defined foreign-data wrappers pg_dump: reading user-defined foreign servers pg_dump: reading default privileges pg_dump: reading user-defined collations pg_dump: reading user-defined conversions pg_dump: reading type casts pg_dump: reading transforms pg_dump: reading table inheritance information pg_dump: reading event triggers pg_dump: finding extension tables pg_dump: finding inheritance relationships pg_dump: reading column info for interesting tables pg_dump: finding the columns and types of table "public.pgbench_history" pg_dump: finding the columns and types of table "public.pgbench_tellers" pg_dump: finding the columns and types of table "public.pgbench_accounts" pg_dump: finding the columns and types of table "public.pgbench_branches" pg_dump: flagging inherited columns in subtables pg_dump: reading indexes pg_dump: reading indexes for table "public.pgbench_tellers" pg_dump: reading indexes for table "public.pgbench_accounts" pg_dump: reading indexes for table "public.pgbench_branches" pg_dump: flagging indexes in partitioned tables pg_dump: reading extended statistics pg_dump: reading constraints pg_dump: reading triggers pg_dump: reading rewrite rules pg_dump: reading policies pg_dump: reading row security enabled for table "public.pgbench_history" pg_dump: reading policies for table "public.pgbench_history" pg_dump: reading row security enabled for table "public.pgbench_tellers" pg_dump: reading policies for table "public.pgbench_tellers" pg_dump: reading row security enabled for table "public.pgbench_accounts" pg_dump: reading policies for table "public.pgbench_accounts" pg_dump: reading row security enabled for table "public.pgbench_branches" pg_dump: reading policies for table "public.pgbench_branches" pg_dump: reading publications pg_dump: reading publication membership pg_dump: reading subscriptions pg_dump: reading large objects pg_dump: reading dependency data pg_dump: saving encoding = UTF8 pg_dump: saving standard_conforming_strings = on pg_dump: saving search_path = pg_dump: saving database definition pg_dump: dumping contents of table "public.pgbench_accounts" pg_dump: dumping contents of table "public.pgbench_branches" pg_dump: dumping contents of table "public.pgbench_history" pg_dump: dumping contents of table "public.pgbench_tellers" [ec2-user@bastin ~]$ リストア用のデータベース作成 [ec2-user@bastin ~]$ psql -h auroratest1.cluster-xxxxxxx.ap-northeast-1.rds.amazonaws.com -d postgres -U postgres -c "create database pgbench_restore" CREATE DATABASE リストア用データベースに個別のテーブルをリストア pgbench_accountsだけをリストア [ec2-user@bastin ~]$ pg_restore -v -h auroratest1.cluster-xxxxxxx.ap-northeast-1.rds.amazonaws.com -U postgres -d pgbench_restore -t pgbench_accounts pgbench.dump pg_restore: connecting to database for restore pg_restore: creating TABLE "public.pgbench_accounts" pg_restore: processing data for table "public.pgbench_accounts" [ec2-user@bastin ~]$ psql -h auroratest1.cluster-xxxxxxx.ap-northeast-1.rds.amazonaws.com -d pgbench_restore -U postgres psql (11.12, server 10.14) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES128-GCM-SHA256, bits: 128, compression: off) Type "help" for help. pgbench_restore=> \conninfo You are connected to database "pgbench_restore" as user "postgres" on host "auroratest1.cluster-xxxxxxx.ap-northeast-1.rds.amazonaws.com" at port "5432". SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES128-GCM-SHA256, bits: 128, compression: off) pgbench_restore=> \d List of relations Schema | Name | Type | Owner --------+------------------+-------+---------- public | pgbench_accounts | table | postgres (1 row) pgbench_restore=> --- ### awswranglerを使用してCSV to Parquet date: 2021-10-22 url: https://zatoima.github.io/aws-athena-glue-awswrangler-csv-to-parquet/ tags: Athena, Glue テスト用CSVの作成 cat << EOF > testdata.csv id,name,comment "1","test1","ゎぶばあちあぬナクバ" "2","test2","がマうひバぴじクハぺ" "3","test3","スみでてゥあッあけげ" EOF S3のフォルダのクリーンアップ awswranglerのオプションでクリーンアップ出来たと思うが、手動で事前に削除 aws s3 rm s3://202110test/pq/ CSV→Parquetに変換 import awswrangler as wr import pandas as pd #変換 df = pd.read_csv('./testdata.csv') wr.s3.to_parquet( df=df, path='s3://202110test/pq/', dataset=True, partition_cols=['id'] ) Athenaでデータベース、データカタログの作成 コンソールから実施を想定 DROP TABLE `catalogtest`.`testdata`; CREATE EXTERNAL TABLE `catalogtest`.`testdata`( `id` string, `name` string, `comment` string ) ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' LOCATION 's3://202110test/pq/' TBLPROPERTIES ( 'classification'='parquet', 'compressionType'='none', 'objectCount'='1', 'typeOfData'='file') MSCK REPAIR TABLE catalogtest.testdata; select name,comment from testdata; athenacliを使用してAthenaのクエリを実行 athenacli catalogtest -e 'select name,comment from testdata' [ec2-user@ip-10-0-1-31 pyarrow]$ athenacli catalogtest -e 'select name,comment from testdata' name,comment test1,ゎぶばあちあぬナクバ test3,スみでてゥあッあけげ test2,がマうひバぴじクハぺ --- ### speedtest-cliを使用してWifi環境の回線速度の可視化 date: 2021-10-20 url: https://zatoima.github.io/speedtest-cli-visualize-wifi-env/ tags: その他 引越し前に自宅インターネット環境の劣悪さを可視化しておく。引越し後にどうなるか楽しみ。 前提 自宅のインターネット環境はマンション付属の無料で使えるものを使っています。 データ取得 実行環境の構築 cd /d D:\tool\python\speedtest git clone https://github.com/sivel/speedtest-cli cd speedtest-cli/ python speedtest.py 実行ログ D:\tool\python\speedtest>git clone https://github.com/sivel/speedtest-cli Cloning into 'speedtest-cli'... remote: Enumerating objects: 1177, done. remote: Counting objects: 100% (17/17), done. remote: Compressing objects: 100% (10/10), done. remote: Total 1177 (delta 6), reused 13 (delta 5), pack-reused 1160 Receiving objects: 100% (1177/1177), 328.93 KiB | 135.00 KiB/s, done. Resolving deltas: 100% (695/695), done. D:\tool\python\speedtest>cd speedtest-cli/ D:\tool\python\speedtest\speedtest-cli>python speedtest.py Retrieving speedtest.net configuration... Testing from Biglobe (60.237.50.214)... Retrieving speedtest.net server list... Selecting best server based on ping... Hosted by NEVERLOSS LLC. (Tokyo) [11.98 km]: 16.147 ms Testing download speed................................................................................ Download: 4.73 Mbit/s Testing upload speed...................................................................................................... Upload: 1.39 Mbit/s CLIで実行 speedtest.py --csv >> result.csv 出力結果 id,test_server,city,date,distance,rtt,download,upload,,ip 14623,IPA CyberLab,Bunkyo,2021-10-17T04:59:01.153340Z,2.1137195505386357,10.001,16558788.37488678,85872237.08767469,,xxx.xxx.xxx Windowsのタスクスケジューラで定期実行 3日分を10分感覚で取得し続ける例。さすがに間隔が短すぎると感じて30分に変更しました。 可視化 安定しているときで10MB/Sec、悪い時は1MB/sec。これでリモートワークやれているのが凄い… --- ### ThinkPad X13 Gen 2 AMD を購入しました date: 2021-10-18 url: https://zatoima.github.io/buy-thinkpad-x13-gen2-amd/ tags: その他 ThinkPad X13 Gen2 AMDを購入した。168,828円でした。 購入を決断した理由 約1.19kgの軽量ボディで持ち運びがしやすい zen3アーキテクチャのRyzen 7 PRO 5850Uを使いたかった。8コア16スレッド! 下記のようにメモリとSSDの追加カスタマイズをしても全体的に見るとリーズナブルに感じた メモリを32GB。LPDDR4Xは良いと聞く SSDストレージ 512GB Type 2280のM.2 SSDが搭載されているが、4G/5Gを選択した時に、通信モジュールを搭載するためのスロットがあり、ここにType 2242のM.2スロットがある。以前に使っていたType 2242 M.2 SSDがあるので有効活用したい(この対応はあくまでも自己責任) T470sのときに特に問題なかった LenovoのThinkpadが好き。トラックポイントが好き 欠点 自分が慣れないだけかもしれないが、ThinkpadのCtrlとFnキーの位置は慣れない。全パソコン、全キーボードをlenovoに寄せる必要があると思っている。 キーマッピングを変えてもいいけど、気持ち悪い スペック プロセッサー : AMD Ryzen 7 PRO 5850U (1.90GHz, 16MB L3) 初期導入OS : Windows 10 Home 64bit 導入OS言語 : Windows 10 Home 64bit - 日本語版 メモリー : 32 GB LPDDR4X-4266MHz (オンボード) 1st SSD : 512GB ソリッドステートドライブ (M.2 2280, PCIe-NVMe) OPAL対応 ディスプレイ : 13.3型WUXGA液晶(1920x1200)IPS、光沢なし、300nit、狭額縁、マルチタッチ非対応、72%NTSC 本体カラー : ブラック トップカバー : PPS (ポリフェニレンサルファイド) グラフィックス : 内蔵グラフィックス 内蔵カメラ : 720p HDカメラ (マイク付) ワイヤレス LAN アダプター : インテル Wi-Fi 6 AX200 (2x2) + Bluetooth (vPro対応) WWAN : Quectel EM120R-GL 4G LTE CAT12 指紋センサー : 指紋センサー (ブラック) ポインティング・デバイス : WWAN、NFC なし、ブラック、マグネシウム キーボード : 日本語キーボード カード・スロット : スマートカードリーダーなし TPMセッティング : TPMあり(TCG V2.0準拠,ハードウェアチップ搭載) Absolute BIOS Selection : BIOS Absolute有効 バッテリー : 4セル リチウムイオンバッテリー (54.7Wh) 電源アダプター : 65W ACアダプター (2ピン)(USB Type-C) Display Panel : 13.3型WUXGA液晶(1920x1200)IPS、光沢なし、300nit、狭額縁、マルチタッチ非対応、72%NTSC、720p HDカメラ、マイク、WWAN非対応、 FreeSync、PPS、ブラック Language Pack : 日本語 標準保証 : 1年間 引き取り修理 --- ### metabaseのアップグレード方法 date: 2021-10-16 url: https://zatoima.github.io/metabase-how-to-upgrade/ tags: metabase アップデートの有無確認 公式ページや公式Twitterからも当然確認出来るが、管理者画面からも有無は分かる。アップデートボタンをクリックした場合、マニュアルに飛ばされるだけなので注意。 アップデート方法 metabaseのサービスを停止 sudo systemctl stop metabase.service wgetで最新のjarファイルを取得 最新のダウンロード先はこちら→ https://www.metabase.com/start/oss/jar コマンド cd /opt/metabase mv -f metabase.jar metabase.jar.bk wget https://downloads.metabase.com/v0.41.0/metabase.jar ls -l sudo systemctl status metabase.service 実行ログ [ec2-user@bastin metabase]$ pwd /opt/metabase [ec2-user@bastin metabase]$ sudo systemctl stop metabase.service [ec2-user@bastin metabase]$ echo $? 0 [ec2-user@bastin metabase]$ cd /opt/metabase [ec2-user@bastin metabase]$ mv -f metabase.jar metabase.jar.bk [ec2-user@bastin metabase]$ wget https://downloads.metabase.com/v0.41.0/metabase.jar --2021-10-15 20:32:50-- https://downloads.metabase.com/v0.41.0/metabase.jar Resolving downloads.metabase.com (downloads.metabase.com)... 18.65.214.22, 18.65.214.55, 18.65.214.111, ... Connecting to downloads.metabase.com (downloads.metabase.com)|18.65.214.22|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 273601461 (261M) [application/java-archive] Saving to: ‘metabase.jar’ 100%[===============================================================================================================================================================================================================================================>] 273,601,461 105MB/s in 2.5s 2021-10-15 20:32:53 (105 MB/s) - ‘metabase.jar’ saved [273601461/273601461] [ec2-user@bastin metabase]$ ls -l total 532200 -rw-r--r-- 1 root root 733184 Sep 14 20:03 metabase.db.mv.db -rw-r--r-- 1 root root 292207 Sep 14 20:03 metabase.db.trace.db -rw-rw-r-- 1 ec2-user ec2-user 273601461 Oct 7 06:34 metabase.jar -rwxr-xr-x 1 ec2-user ec2-user 270334859 Aug 26 04:42 metabase.jar.bk drwxr-xr-x 2 root root 4096 Sep 9 19:58 plugins [ec2-user@bastin metabase]$ sudo systemctl status metabase.service ● metabase.service - Metabase. Loaded: loaded (/usr/lib/systemd/system/metabase.service; enabled; vendor preset: disabled) Active: active (running) since Fri 2021-10-15 20:34:36 JST; 1min 22s ago Process: 3315 ExecStop=/bin/kill -SIGTERM $MAINPID (code=exited, status=0/SUCCESS) Main PID: 3374 (java) CGroup: /system.slice/metabase.service └─3374 /usr/bin/java -jar /opt/metabase/metabase.jar Oct 15 20:35:21 bastin metabase[3374]: 2021-10-15 20:35:21,224 INFO metabase.task :: タスク CheckForNewVersions を初期化しています Oct 15 20:35:21 bastin metabase[3374]: 2021-10-15 20:35:21,284 INFO metabase.task :: タスク SendAnonymousUsageStats を初期化しています Oct 15 20:35:21 bastin metabase[3374]: 2021-10-15 20:35:21,309 INFO metabase.task :: タスク SendAbandomentEmails を初期化しています Oct 15 20:35:21 bastin metabase[3374]: 2021-10-15 20:35:21,330 INFO metabase.task :: タスク SendPulses を初期化しています Oct 15 20:35:21 bastin metabase[3374]: 2021-10-15 20:35:21,354 INFO metabase.task :: タスク SendFollowUpEmails を初期化しています Oct 15 20:35:21 bastin metabase[3374]: 2021-10-15 20:35:21,370 INFO metabase.task :: タスク TaskHistoryCleanup を初期化しています Oct 15 20:35:21 bastin metabase[3374]: 2021-10-15 20:35:21,407 INFO driver.impl :: ドライバー:sqlの初期化中です... Oct 15 20:35:21 bastin metabase[3374]: 2021-10-15 20:35:21,410 INFO driver.impl :: ドライバー:sql-jdbcの初期化中です... Oct 15 20:35:21 bastin metabase[3374]: 2021-10-15 20:35:21,411 INFO driver.impl :: ドライバー:h2の初期化中です... Oct 15 20:35:21 bastin metabase[3374]: 2021-10-15 20:35:21,439 INFO metabase.core :: Metabaseの初期化が完了しました [ec2-user@bastin metabase]$ アップデート後の確認 --- ### CDMP取得に向けたメモ date: 2021-10-14 url: https://zatoima.github.io/dmbok-memo-for-cdmp-acquisition/ tags: DMBOK, CDMP モチベーション データ基盤、データレイク、データ分析基盤等を作っていくにあたってインフラ周りだけではなく、実際にはデータをどのように収集して、管理して、品質を高めてビジネスに活かしていくかというデータマネージメントの観点も必要で、そこの知識を断片的な状況から一歩引き上げて網羅的に身に着けたいと考えた。データエンジニアリング的な要素は後述のDMBOKでいうとデータマネージメント領域の一領域なのでここだけの観点で構築しても実際には意味がない。 CDMP&DMBOKの参考リンク データマネジメントの知識体系"DMBOK"とは?どう役立つのか? CDMP Associate 認定を取得した話 - Qiita 2週間で合格!CDMP合格体験記 | Metafindコンサルティング CDMPを取得した話|へなちょこ|note CDMPとは CDMP(Certified Data Management Professionals)は、DAMA(Data Management Association)が認定しているデータマネジメントに関する国際資格のこと。DAMAはData Management Body of Knowledge(DMBOK)というデータマネジメントに関する知識体系をまとめており、PMBOKのデータマネージメントという思っていれば良い。 CDMPに認定されるためには 複数のレベルがあり、Data Management Fundamentls ExamとSpecialist Examを受けることによってそれぞれのレベルに認定される。一番最初のstepとしてはData Management Fundamentls Examを60%以上の成績でpassすること。 https://cdmp.info/about/ Data Management Fundamentls Examの問題傾向 下記の通りの配点なので、重要な分野を中心に勉強していくのが良さそう。 No 分野 配点 1 データガバナンス 11% 2 データのモデリングと設計 11% 3 データ品質 11% 4 メタデータ管理 11% 5 マスターおよび参照データ管理 10% 6 データウェアハウジングとビジネスインテリジェンス 10% 7 データアーキテクチャ 6% 8 ドキュメントとコンテンツの管理 6% 9 データ統合と相互運用性 6% 10 データセキュリティ 6% 11 データの保存と運用 6% 12 データ管理プロセス 2% 13 ビッグデータ 2% 14 データ倫理 2% 勉強方針 業務中に必要に応じて参照しつつあったが、改めて下記3点を通読、及び視聴しようと思う。その後、模試を受ける。 データマネジメント知識体系ガイド 第二版 https://www.amazon.co.jp/dp/4296100491 データマネジメントが30分でわかる本 https://www.amazon.co.jp/dp/B085W4YSZJ 【初学者向け】データマネジメント入門!DX推進やAI 導入を支える重要な要素をDMBOKに沿ってみていこう! | Udemy https://www.udemy.com/course/data-management/ --- ### RSSがないサイトの更新情報を受け取る方法 date: 2021-10-13 url: https://zatoima.github.io/how-to-know-the-update-information-of-the-site-without-rss/ tags: その他 RSSがオワコンと言われて数年未だにRSSを使っています。RSSを配信していないサイトが多いのでどうしたものかと思っていたらサイト更新を検知して通知してくれるサービスがあることを知りました。この2つのサービスが良さそう。使ってみて感想を書きます。 Distill web monitor Page Monitor --- ### metabaseの公式情報 date: 2021-09-29 url: https://zatoima.github.io/metabase-official-documentation/ tags: metabase 他のBIツールと比較してこの機能ないのか?みたいな疑問、質問はhttps://discourse.metabase.com/で議論されているので確認すべし Metabase Documentation https://www.metabase.com/docs/latest/ Issues · metabase/metabase · GitHub https://github.com/metabase/metabase/issues Metabase Discussion https://discourse.metabase.com/ --- ### Windows10でssh-keygen date: 2021-09-23 url: https://zatoima.github.io/windows10-ssh-keygen-generate/ tags: Windows OpenSSHがWindows10に標準搭載されていることでssh-keygenも使えるようになっていることに気づく。Puttyとか入れる必要が無く便利 cd /d D:\key ssh-keygen.exe -q -t rsa -b 4096 -C "" -N "" -f gcp-for-keypair 作成される鍵 gcp-for-keypair.pub:公開鍵 gcp-for-keypair:秘密鍵 --- ### Redshift Spectrumのベストプラクティス date: 2021-09-20 url: https://zatoima.github.io/aws-redshift-spectrum-best-practice/ tags: AWS, Redshift 殴り書きメモ 参考 Amazon Redshift Advanced Guide − 最新ベストプラクティスとアップデート https://d1.awsstatic.com/webinars/jp/pdf/services/20200729_AWS_BlackBelt_RedshiftAdvancedGuide.pdf Amazon Redshift Spectrum 12 のベストプラクティス | Amazon Web Services ブログ https://aws.amazon.com/jp/blogs/news/10-best-practices-for-amazon-redshift-spectrum/ ベストプラクティス ファイル/テーブル属性 列志向フォーマット(Purquet) 必要な列のみを選択 最適なファイルサイズ 適切なデータ型 パーティションプルーニング 不要なパーティションをSkipさせるため コスト削減 Spectrum Usage Limitというアラームを上げる機能がある Min/Maxプルーニング Parquet, ORCなど列指向フォーマットの最小/最大値の統計を活用する 頻繁に絞り込みを行うカラムでデータをソートしておくと効果的 Spectrum層へのプッシュダウン 頻繁に絞り込みを行うカラムでデータをソートしておくと効果的 最後に実行されたクエリの詳細を取得 select query, segment, elapsed, s3_scanned_rows, s3_scanned_bytes, s3query_returned_rows, s3query_returned_bytes, files from svl_s3query_summary where query = pg_last_query_id() order by query,segment; https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_SVL_S3QUERY_SUMMARY.html データレイアウト データレイアウトを意識する 実行計画の最適化 テーブルプロパティのnumRowsを更新する ANALYZE等で更新出来ない ALTER TABLE spectrum_schema.eventSET TABLE PROPERTIES (’numRows’=‘122857504’); もしくはGlue Data Catalog側を更新 Redshift クラスターサイズ 並列度を上げるためにはノード数を増やす必要がある。 スライス数の確認 select node,count(slice) from stv_slices group by node order by node; スライス毎のリクエストは最大10となる --- ### EMR PySparkにspark-submitで実行 date: 2021-09-18 url: https://zatoima.github.io/aws-emr-pyspark-spark-submit-command.html tags: AWS, EMR 実行用ファイル作成 vi test.py from pyspark.sql.types import * from pyspark.context import SparkContext from pyspark.sql.session import SparkSession sc = SparkContext('local') spark = SparkSession(sc) def test_pyspark_sql(): schema = StructType([ StructField('file', StringType(), False), StructField('num', IntegerType(), False), StructField('row', IntegerType(), False), StructField('word', StringType(), False), StructField('subtype1', StringType(), False), StructField('subtype2', StringType(), False), StructField('subtype3', StringType(), False), StructField('subtype4', StringType(), False), StructField('conjtype', StringType(), False), StructField('conjugation', StringType(), False), StructField('basic', StringType(), False), StructField('ruby', StringType(), False), StructField('pronunce', StringType(), False) ]) df = spark.read.csv(f's3://sparkwdcnt/utf8_all.csv', schema=schema, header=True) df.groupBy('word').count().sort('count', ascending=False).show(30) df.write.mode("overwrite").option("header", "True").csv(f's3://sparkwdcnt/utf8_all_count.csv') if __name__ == "__main__": print("test Start") test_pyspark_sql() print("test end") 実行 spark-submit --class org.apache.spark.examples.SparkPi /home/hadoop/test.py spark-submitのオプション [hadoop@ip-172-31-2-204 ~]$ spark-submit --help Usage: spark-submit [options] <app jar | python file | R file> [app arguments] Usage: spark-submit --kill [submission ID] --master [spark://...] Usage: spark-submit --status [submission ID] --master [spark://...] Usage: spark-submit run-example [options] example-class [example args] Options: --master MASTER_URL spark://host:port, mesos://host:port, yarn, k8s://https://host:port, or local (Default: local[*]). --deploy-mode DEPLOY_MODE Whether to launch the driver program locally ("client") or on one of the worker machines inside the cluster ("cluster") (Default: client). --class CLASS_NAME Your application's main class (for Java / Scala apps). --name NAME A name of your application. --jars JARS Comma-separated list of jars to include on the driver and executor classpaths. --packages Comma-separated list of maven coordinates of jars to include on the driver and executor classpaths. Will search the local maven repo, then maven central and any additional remote repositories given by --repositories. The format for the coordinates should be groupId:artifactId:version. --exclude-packages Comma-separated list of groupId:artifactId, to exclude while resolving the dependencies provided in --packages to avoid dependency conflicts. --repositories Comma-separated list of additional remote repositories to search for the maven coordinates given with --packages. --py-files PY_FILES Comma-separated list of .zip, .egg, or .py files to place on the PYTHONPATH for Python apps. --files FILES Comma-separated list of files to be placed in the working directory of each executor. File paths of these files in executors can be accessed via SparkFiles.get(fileName). --conf, -c PROP=VALUE Arbitrary Spark configuration property. --properties-file FILE Path to a file from which to load extra properties. If not specified, this will look for conf/spark-defaults.conf. --driver-memory MEM Memory for driver (e.g. 1000M, 2G) (Default: 1024M). --driver-java-options Extra Java options to pass to the driver. --driver-library-path Extra library path entries to pass to the driver. --driver-class-path Extra class path entries to pass to the driver. Note that jars added with --jars are automatically included in the classpath. --executor-memory MEM Memory per executor (e.g. 1000M, 2G) (Default: 1G). --proxy-user NAME User to impersonate when submitting the application. This argument does not work with --principal / --keytab. --help, -h Show this help message and exit. --verbose, -v Print additional debug output. --version, Print the version of current Spark. Cluster deploy mode only: --driver-cores NUM Number of cores used by the driver, only in cluster mode (Default: 1). Spark standalone or Mesos with cluster deploy mode only: --supervise If given, restarts the driver on failure. --kill SUBMISSION_ID If given, kills the driver specified. --status SUBMISSION_ID If given, requests the status of the driver specified. Spark standalone and Mesos only: --total-executor-cores NUM Total cores for all executors. Spark standalone and YARN only: --executor-cores NUM Number of cores per executor. (Default: 1 in YARN mode, or all available cores on the worker in standalone mode) YARN-only: --queue QUEUE_NAME The YARN queue to submit to (Default: "default"). --num-executors NUM Number of executors to launch (Default: 2). If dynamic allocation is enabled, the initial number of executors will be at least NUM. --archives ARCHIVES Comma separated list of archives to be extracted into the working directory of each executor. --principal PRINCIPAL Principal to be used to login to KDC, while running on secure HDFS. --keytab KEYTAB The full path to the file that contains the keytab for the principal specified above. This keytab will be copied to the node running the Application Master via the Secure Distributed Cache, for renewing the login tickets and the delegation tokens periodically. 参考 Submitting Applications - Spark 3.1.1 Documentation https://spark.apache.org/docs/latest/submitting-applications.html --- ### GCP Associate Cloud Engineer 合格体験記 date: 2021-09-14 url: https://zatoima.github.io/gcp-associate-cloud-engineer-certification/ tags: GCP 育休中で家事や育児とまとまった時間が取りにくい状況だが、何かしらの勉強をしておかないと気持ち的にも育休から復帰しにくいと考えて、隙間時間を見つけてGCPの勉強してみた。モチベーションはGCP Professional Data Engineerを取るための前準備。 試験概要 Associate Cloud Engineer 認定資格 | Google Cloud https://cloud.google.com/certification/cloud-engineer 試験ガイド Associate Cloud Engineer 認定資格 認定試験ガイド | Google Cloud https://cloud.google.com/certification/guides/cloud-engineer 受験者のクラウド/GCP知識 AWS12冠 AZ-900: Microsoft Azure Fundamentals GCPはGCEのAlways Freeに惹かれてWordpressをデプロイして放置した経験あり BigQueryとCloud Spannerはセミナー資料を読んで勉強してたりしました 勉強時間 約2週間 勉強ステップ Coursera や Qwiklabsは流し気味にやりました。 書籍「GCPの教科書」を読む 書籍「Google Cloud Platform エンタープライズ設計ガイド」を読む Associate Cloud Engineer 模擬試験をやってみる Qwiklabs のクエスト Google Cloud Essentials Cloud Engineering Baseline: Infrastructure Cloud Architecture Coursera Architecting with Google Compute Engine 日本語版専門講座 Google Cloud Platform Fundamentals: Core Infrastructure 日本語版 Essential Cloud Infrastructure: Foundation 日本語版 Essential Cloud Infrastructure: Core Services 日本語版 Elastic Cloud Infrastructure: Scaling and Automation 日本語版 Preparing for the Google Cloud Associate Cloud Engineer Exam Udemyの問題集をやってみる GCP Associate Cloud Engineer チートシート から関連する公式マニュアルを確認する [Master] GCP Getting Started JP GCPUG公開資料 GCPのチュートリアル Cloud OnAirでメインサービスのセッション資料を読む 感想 プロジェクト間のリソースの移動とかデータの移動方法、そのときの権限等はあまり勉強していなかったので焦った。模擬試験と問題傾向が違うな、と感じた ただの知識一辺倒の試験ではなく、実際の業務でも聞かれそうなことを試験でも聞いてきているなって感じた AWSとの設計思想の違いやサービスラインナップの違い等が勉強してて面白かった 次はGCP Professional Data Engineerを予定 --- ### gmailを使用してmetabaseのメール設定(Dashboard subscriptions)を行う date: 2021-09-12 url: https://zatoima.github.io/metabase-gmail-email-sent-how-to/ tags: metabase metabaseにはダッシュボードを共有するときにSlackやメールを選べるわけですが、メールをgmailで設定するときの設定値、設定方法をまとめておきます。ビジネス用途ではgmailで送信するという需要ないと思います。個人では中々メールサーバ立てるのはめんどくさいと思うのでgmailで出来れば便利かと思います。 参考資料 Dashboard Subscriptions https://www.metabase.com/docs/latest/users-guide/dashboard-subscriptions.html Setting Up Email https://www.metabase.com/docs/latest/administration-guide/02-setting-up-email.html セットアップ画面 入力値 SMTPホスト: smtp.gmail.com SMTPポート: 587 SMTPセキュリティ: TLS SMTPユーザー名: GMailアカウント(email@gmail.com) SMTPパスワード:gmailのパスワード その他設定するところ 上記の入力値をmetabaseから設定すると失敗しました。理由は、gmailからすると安全性の低いアプリと認定されるようです。こちらの記事を確認して、安全性の低いアプリのアクセスを有効化します。一応、念の為に普段使い用のgmailアカウントではなく、送信用のgmailのアカウントを作成しました。 https://support.google.com/accounts/answer/6010255?hl=ja 安全性の低いアプリと Google アカウント ここまで行うことでメール設定が完了。後は選択項目の通りに設定して、メールを送信する。 --- ### Redshift Spectrum用にテストデータの準備、及びクエリの実行 date: 2021-09-10 url: https://zatoima.github.io/aws-redshift-spectrum-data-prepare-query-execute/ tags: AWS, Redshift はじめに 一定のテストデータ、及び多少の負荷が掛かるSQLをRedshift Spectrumに向けて実行したい場合の作業用メモ。 データ確認 データはs3://awssampledbuswest2/ssbgz/から自バケットに予めコピーしている aws s3 ls --human-readable --recursive s3://ssbgz-spectrum/ [ec2-user@bastin ~]$ aws s3 ls --human-readable --recursive s3://ssbgz-spectrum/ 2021-06-15 16:10:10 100.5 MiB customer/customer0002_part_00.gz 2021-06-15 16:10:10 24.6 KiB dwdate/dwdate.tbl.gz 2021-06-15 16:10:10 3.1 GiB lineorder/lineorder0000_part_00.gz 2021-06-15 16:10:10 3.1 GiB lineorder/lineorder0001_part_00.gz 2021-06-15 16:10:11 3.1 GiB lineorder/lineorder0002_part_00.gz 2021-06-15 16:10:10 3.1 GiB lineorder/lineorder0003_part_00.gz 2021-06-15 16:10:14 3.1 GiB lineorder/lineorder0004_part_00.gz 2021-06-15 16:11:47 3.1 GiB lineorder/lineorder0005_part_00.gz 2021-06-15 16:12:16 3.1 GiB lineorder/lineorder0006_part_00.gz 2021-06-15 16:12:26 3.1 GiB lineorder/lineorder0007_part_00.gz 2021-06-15 16:12:35 8.3 MiB part/part0000_part_00.gz 2021-06-15 16:12:36 8.3 MiB part/part0001_part_00.gz 2021-06-15 16:12:38 8.3 MiB part/part0002_part_00.gz 2021-06-15 16:12:39 8.3 MiB part/part0003_part_00.gz 2021-06-15 16:12:40 32.5 MiB supplier/supplier.tbl_0000_part_00.gz 2021-06-15 16:12:42 20 Bytes supplier/supplier0001_part_00.gz 2021-06-15 16:12:42 20 Bytes supplier/supplier0002_part_00.gz 2021-06-15 16:12:42 20 Bytes supplier/supplier0003_part_00.gz 外部スキーマ定義 create external schema s3 from data catalog database 's3_spectrum' iam_role 'arn:aws:iam::xxxxxxxxxxx:role/myRedshiftRole' create external database if not exists; mydb=# create external schema s3 from data catalog mydb-# database 's3_spectrum' mydb-# iam_role 'arn:aws:iam::xxxxxxxxxxx:role/myRedshiftRole' mydb-# create external database if not exists; INFO: External database "s3_spectrum" already exists CREATE SCHEMA 外部表の定義 drop table s3.part; CREATE EXTERNAL TABLE s3.part ( p_partkey INTEGER, p_name VARCHAR(22), p_mfgr VARCHAR(6), p_category VARCHAR(7), p_brand1 VARCHAR(9), p_color VARCHAR(11), p_type VARCHAR(25), p_size INTEGER, p_container VARCHAR(10)) row format delimited fields terminated by '|' stored as textfile LOCATION 's3://ssbgz-spectrum/part/'; drop table s3.supplier; CREATE EXTERNAL TABLE s3.supplier ( s_suppkey INTEGER, s_name VARCHAR(25), s_address VARCHAR(25), s_city VARCHAR(10), s_nation VARCHAR(15), s_region VARCHAR(12), s_phone VARCHAR(15)) row format delimited fields terminated by '|' stored as textfile LOCATION 's3://ssbgz-spectrum/supplier/'; drop table s3.customer; CREATE EXTERNAL TABLE s3.customer ( c_custkey INTEGER, c_name VARCHAR(25), c_address VARCHAR(25), c_city VARCHAR(10), c_nation VARCHAR(15), c_region VARCHAR(12), c_phone VARCHAR(15), c_mktsegment VARCHAR(10)) row format delimited fields terminated by '|' stored as textfile LOCATION 's3://ssbgz-spectrum/customer/'; drop table s3.dwdate; CREATE EXTERNAL TABLE s3.dwdate ( d_datekey INTEGER, d_date VARCHAR(19), d_dayofweek VARCHAR(10), d_month VARCHAR(10), d_year INTEGER, d_yearmonthnum INTEGER, d_yearmonth VARCHAR(8), d_daynuminweek INTEGER, d_daynuminmonth INTEGER, d_daynuminyear INTEGER, d_monthnuminyear INTEGER, d_weeknuminyear INTEGER, d_sellingseason VARCHAR(13), d_lastdayinweekfl VARCHAR(1), d_lastdayinmonthfl VARCHAR(1), d_holidayfl VARCHAR(1), d_weekdayfl VARCHAR(1)) row format delimited fields terminated by '|' stored as textfile LOCATION 's3://ssbgz-spectrum/dwdate/'; drop table s3.lineorder; CREATE EXTERNAL TABLE s3.lineorder ( lo_orderkey INTEGER, lo_linenumber INTEGER, lo_custkey INTEGER, lo_partkey INTEGER, lo_suppkey INTEGER, lo_orderdate INTEGER, lo_orderpriority VARCHAR(15), lo_shippriority VARCHAR(1), lo_quantity INTEGER, lo_extendedprice INTEGER, lo_ordertotalprice INTEGER, lo_discount INTEGER, lo_revenue INTEGER, lo_supplycost INTEGER, lo_tax INTEGER, lo_commitdate INTEGER, lo_shipmode VARCHAR(10)) row format delimited fields terminated by '|' stored as textfile LOCATION 's3://ssbgz-spectrum/lineorder/'; テストクエリ SELECT c_city, s_city, d_year, SUM(lo_revenue) AS revenue FROM s3.customer, s3.lineorder, s3.supplier, s3.dwdate WHERE lo_custkey = c_custkey AND lo_suppkey = s_suppkey AND lo_orderdate = d_datekey AND (c_city='UNITED KI1' OR c_city='UNITED KI5') AND (s_city='UNITED KI1' OR s_city='UNITED KI5') AND d_yearmonth = 'Dec1997' GROUP BY c_city, s_city, d_year ORDER BY d_year ASC, revenue DESC; --- ### GCP Associate Cloud Engineer 認定試験ガイド - クラウド ソリューションの計画と構成 date: 2021-09-07 url: https://zatoima.github.io/gcp-associate-cloud-engineer-exam-guide-2/ tags: GCP はじめに GCP Associate Cloud Engineerの受験に向けて試験ガイド記載のマニュアル確認と一部実機確認を行って、試験ガイドに沿った勉強を実施する。大項目レベルでは下記の5つが試験範囲となる。 クラウド ソリューション環境の設定 クラウド ソリューションの計画と構成 クラウド ソリューションのデプロイと実装 クラウド ソリューションの正常なオペレーションの確保 アクセスとセキュリティの構成 認定試験ガイドにはこの大項目が細分化されており、この一つ一つを掘り下げて下記のように具体的な出題項目が設定されているようだ。 今回はクラウド ソリューションの計画と構成に対して確認を行う。 2. クラウド ソリューションの計画と構成 2.1 料金計算ツールを使用して GCP プロダクトの使用量を計画して見積もる Google Cloud Pricing Calculatorを使用して見積もる 参考:Google Cloud Platform 料金計算ツール 2.2 コンピューティング リソースを計画、構成する。以下のような点を考察します。 ワークロードに適したコンピューティング サービス(例: Compute Engine、Google Kubernetes Engine、App Engine、Cloud Run、Cloud Functions)の選択 多くのホスティングオプションがある。デプロイ形式からディスクの必要有無、スケーリングの速さ等のユースケースから最適なコンピューティングサービスを選択する必要あり。 参考:アプリケーションのホスティングのオプション | Hosting Options | Google Cloud プリエンプティブル VM とカスタム マシンタイプの適宜使用 プリエンプティブル VM インスタンス プリエンプティブル VM は、通常のインスタンスよりはるかに低価格で作成、実行できるインスタンスです。ただし、他のタスクがリソースへのアクセスを必要とする場合、Compute Engine がこのインスタンスを停止(プリエンプト)する可能性があります。プリエンプティブル インスタンスは Compute Engine の余剰のキャパシティを利用する機能であり、使用できるかどうかは利用状況に応じて異なります。 AWSのスポットインスタンスのようなもの プリエンプティブル VM インスタンス | Compute Engine ドキュメント | Google Cloud カスタム マシンタイプ 事前定義されたマシンタイプがニーズに合わない場合は、カスタムの仮想ハードウェア設定を使用して VM インスタンスを作成できます。具体的には、カスタム マシンタイプを効果的に利用して、vCPU の数とメモリ容量をカスタマイズした VM インスタンスを作成できます。 カスタム VM インスタンスの作成 | Compute Engine ドキュメント | Google Cloud gcloudコマンドで作成する際には--custome-cpuや--customer-memoryをオプションに使う gcloud compute instances create example-instance --custom-cpu=4 --custom-memory=5 既存のインスタンスに対してもメモリを追加出来るようで便利な機能だと思った 各マシンタイプには、マシンに応じてデフォルトで特定のメモリ量が設定されています。たとえば、カスタム N1 VM を作成する場合は、vCPU あたり最大 6.5 GB のメモリを設定できます。カスタム N2 VM の場合、この数値は vCPU あたり最大 8 GB のメモリに引き上げられます。 2.3 データ ストレージ オプションを計画、構成する。以下のような点を考察します。 プロダクト(例: Cloud SQL、BigQuery、Cloud Spanner、Cloud Bigtable)の選択 トランザクションが必要なのか、水平スケーリングが必要なのか、SQLベースの分析クエリが必要なのか、大規模で低レイテンシのワークロードに対応したKey-Value型のデータストアが必要なのか、ワールドワイドなリージョンに跨るデータ格納が必要なのか、、みたいな要件に応じて適切なデータストアを検討する Google Cloud データベース ストレージ オプション(例: Standard、Nearline、Coldline、Archive)の選択 ストレージ クラス API と gsutil の名前 最小保存期間 一般的な月間可用性 Standard Storage STANDARD なし マルチリージョンとデュアルリージョンでは 99.99% を超えるリージョンでは 99.99% Nearline Storage NEARLINE 30 日 マルチリージョンとデュアルリージョンでは 99.95%リージョンでは 99.9% Coldline Storage COLDLINE 90 日 マルチリージョンとデュアルリージョンでは 99.95%リージョンでは 99.9% Archive Storage ARCHIVE 365 日 マルチリージョンとデュアルリージョンでは 99.95%リージョンでは 99.9% ストレージ クラス | Cloud Storage | Google Cloud 2.4 ネットワーク リソースを計画、構成する。以下のようなタスクを行います。 負荷分散オプションの違いを見分ける 参考:ロードバランサの選択 | 負荷分散 | Google Cloud 可用性を考慮してネットワーク内のリソースのロケーションを決定する 下記のような要素に注意しつつ、ロケーションを選択する。複数リージョンにデプロイして負荷分散させることや、複数リージョンの分散フロントを実装するが、バックエンドは単一リージョンで構成するか等要件に応じて適切な選択を行う リージョンに固有の制限 リージョンによるユーザー レイテンシ アプリのレイテンシ要件 レイテンシをどの程度制御できるか 低レイテンシとシンプルさのバランス 参考:Compute Engine のリージョン選択に関するベスト プラクティス | ソリューション | Google Cloud Cloud DNS を構成する Cloud DNS は、高パフォーマンスで復元力を備えたグローバル ドメイン ネーム システム(DNS)サービス 用語がGCP用語でスッと入ってこないが、基本はRoute53と同じような特徴、機能を持っているようだ 参考:Cloud DNS の概要 | Google Cloud --- ### GCP Associate Cloud Engineer 認定試験ガイド - クラウド ソリューション環境の設定 date: 2021-09-05 url: https://zatoima.github.io/gcp-associate-cloud-engineer-exam-guide-1/ tags: GCP はじめに GCP Associate Cloud Engineerの受験に向けて試験ガイド記載のマニュアル確認と一部実機確認を行って、試験ガイドに沿った勉強を実施する。大項目レベルでは下記の5つが試験範囲。 クラウド ソリューション環境の設定 クラウド ソリューションの計画と構成 クラウド ソリューションのデプロイと実装 クラウド ソリューションの正常なオペレーションの確保 アクセスとセキュリティの構成 認定試験ガイドにはこの大項目が更に細分化されており、この一つ一つを掘り下げて下記のように具体的な出題項目が設定されているようだ。 まずはクラウド ソリューション環境の設定に対して確認を行う。 1. クラウド ソリューション環境の設定 1.1 クラウド プロジェクトとアカウントを設定する。以下のような作業を行います。 プロジェクトを作成する 参考:プロジェクトの作成と管理 | Resource Manager のドキュメント | Google Cloud Google Cloud プロジェクトは、API の管理、課金の有効化、共同編集者の追加と削除、Google Cloud リソースに対する権限の管理など、すべての Google Cloud サービスの作成、有効化、使用の基礎となる。例えば、本番環境、開発環境を分離したい場合はこのプロジェクトを分ける。AWSの場合はアカウント分割ということになり、それぞれにIAMユーザを作成する。環境(アカウント)の切り替えはIAMスイッチロールを利用することになる。個人的にはGCPの方がわかりやすい気がする。 コンソール画面 gcloudコマンド gcloud projects create PROJECT_ID プロジェクト内で事前定義された IAM ロールにユーザーを割り当てる 参考:プロジェクト、フォルダ、組織へのアクセスを管理する | Cloud IAM のドキュメント | Google Cloud 「IAMと管理」-「IAM」から追加する事前定義されたロール等を選択する。 GCPのIAMの要素は次の通り。AWSと同じようなワードを使っているが、中身が全く異なることに注意が必要。 参考:よくある質問 | Cloud IAM のドキュメント | Google Cloud メンバー:権限を付与される対象のこと。Googleアカウント、サービスアカウント、Googleグループ、G Suite、Cloud Identityドメイン ロール:権限のコレクション。メンバーにロールを付与すると、ロールに含まれる全ての権限が付与される。 基本ロール、事前定義ロール、カスタムロールが存在する。基本ロールはオーナー、編集者、閲覧者のロールがあり、すべてのGCPサービスに影響する。事前定義ロールはGCP側が用意している権限セット。カスタムロールはユーザ側が設定する権限セットとなる。 基本ロールにはこんな注意書きがマニュアルに。 注意: 基本ロールには、すべての Google Cloud サービスにかかわる何千もの権限が含まれます。本番環境では、他に選択肢がない限り、基本ロールを付与しないでください。代わりに、ニーズに合わせて最も制限された事前定義ロールまたはカスタムロールを付与します。 AWSユーザは勘違いしやすいと思うが、GCPのロールはAWSで言うところのIAMポリシー相当になるはず ポリシー:誰(ユーザー)に、どのリソースに対する何(役割)の権限を付与するかを制御 AWSで言うところのバケットポリシーみたいなもの https://cloud.google.com/iam/docs/faq?hl=ja#what_does_an_policy_look_like { "bindings": [ { "role": "roles/owner", "members": [ "user:jiwoo@example.com", "group:admins@example.com", "domain:google.com", "serviceAccount:my-other-app@appspot.gserviceaccount.com"] }, { "role": "roles/compute.networkViewer", "members": ["user:luis@example.com"] } ] } Cloud Identity でユーザーを管理する(手動および自動) GoogleのサービスなのでGCPのアカウントはGoogleアカウントが使用出来る。Googleアカウントを作れない組織、G Suiteを使っている組織等はこのCloud Identifyでアカウントを管理する 参考:GCP 管理者向けの設定手順 - Cloud Identity ヘルプ Cloud Identity は IDaaS(Identity as a Service)ソリューションであり、企業向けモバイル管理(EMM)サービスです。Google Workspace で利用できる ID サービスとエンドポイント管理をスタンドアロン型のサービスとして提供します。Cloud Identity を利用することで、管理者は Google 管理コンソールからユーザー、アプリ、デバイスを一元管理できます。 よくあるMicrosoftのActive Directoryの連携についても対応している模様。 Google Cloud と Active Directory の連携: 概要 | アーキテクチャ プロジェクトで API を有効にする GCPでは使用するサービスのAPIを有効化する必要がある。APIライブラリ画面から、もしくはgcloudから有効化する。 なぜGCPはAPI有効化を行うように設計されているのだろうか こういうワンライナー出てきてしまうの必然… GCPのAPIを全部有効化するワンライナー - Qiita 参考:Google Cloud プロジェクトでの API の有効化 | OpenAPI を使用した Cloud Endpoints APIライブラリから gcloudコマンド gcloud services enable SERVICE_NAME Stackdriver ワークスペースをプロビジョニングする Stackdriverはオペレーション スイートに統合され、特にワークスペースをプロビジョニングするという作業は不要だと思われる オペレーションスイートの概要 Cloud Logging リアルタイムでのログの管理と分析 アプリケーションとシステムのログデータのほか、GKE 環境、VM、Google Cloud サービスからのカスタム ログデータも取り込み可能 Cloud Monitoring 組み込みの大規模な指標オブザーバビリティ クラウドで実行されるアプリケーションのパフォーマンスや稼働時間、全体的な動作状況を確認できます。Google Cloud サービス、ホステッド アップタイムのプローブ、アプリケーション インストルメンテーション、よく使われるさまざまなアプリケーション コンポーネントから指標、イベント、メタデータを収集し、チャートやダッシュボードで可視化してアラートを管理 アプリケーション パフォーマンス管理(APM) Cloud Trace、Cloud Debugger、Cloud Profiler が統合 Cloud Trace 本番環境におけるパフォーマンスのボトルネックを検出 Cloud Trace は、アプリケーションのすべてのトレースを自動的に分析し、パフォーマンス低下の原因となるレイテンシの詳細レポートを生成 Cloud Debugger 本番環境でコードの動作を調査 リアルタイムでのアプリケーションのデバッグ Cloud Profiler パフォーマンス向上やコスト削減に役立つ、CPU とヒープの継続的なプロファイリング 1.2 課金構成を管理する。以下のような作業を行います。 請求先アカウントを作成する billing.accounts.create権限が必要 参考:セルフサービスの Cloud 請求先アカウントの作成、変更、閉鎖 | Cloud Billing | Google Cloud プロジェクトを請求先アカウントにリンクする 参考:プロジェクトの課金の有効化、無効化、変更 | Cloud Billing | Google Cloud 課金の予算とアラートを設定する 参考:予算と予算アラートの設定 | Cloud Billing | Google Cloud 日 / 月単位の料金見積もりを目的として請求関連のエクスポートを設定する BigQuery への Cloud Billing のエクスポート機能を使用することで、指定した BigQuery データセットに Google Cloud の詳細な課金データ(使用量、費用予測、料金データなど)を終日、自動的にエクスポート可能。エクスポートを有効にする前の Cloud Billing データは表示されないことに注意する。 参考:Cloud Billing データを BigQuery にエクスポートする | Google Cloud 1.3 コマンドライン インターフェース(CLI)、具体的には Cloud SDK をインストール、構成する(例: デフォルト プロジェクトの設定) マニュアルのSDK構成と書かれると何を指しているかわからないが、英語にするとConfigurationの模様。プロファイルとか設定とかのニュアンスと理解している 構成を作成する gcloud config configurations create [NAME] 構成を有効にする gcloud config configurations activate [NAME] 構成を一覧表示する gcloud config configurations list 構成のプロパティを設定する gcloud config set project [PROJECT] gcloud config unset project 構成のプロパティを表示する gcloud config configurations describe [NAME] 構成を削除する gcloud config configurations delete [NAME] 参考:SDK 構成の管理 | Cloud SDK のドキュメント | Google Cloud --- ### Hugo wowchemy(旧Academic)における記事幅の調整方法 date: 2021-09-02 url: https://zatoima.github.io/hugo-wowchemy-academic-article-container/ tags: Hugo 下記の通り行うことでカスタマイズが可能。 高度なスタイルのカスタマイズが必要な場合は、既存のスタイルをオーバーライドしたり、強化するための CSS コード を記述することが可能 assets/scss/ フォルダがない場合は作成する。 assets/scss/ フォルダの中に custom.scss という名前のファイルを作成する。 作成したファイルにカスタムCSSコードを追加し、Hugoを再実行して変更を確認する。 適宜、こんな形で指定すれば良い。 .article-container { width: 100%; max-width: 1000px; min-width: 500px; margin-right: auto; margin-left: auto; } 参考 Extending Wowchemy | Wowchemy: Free, No Code Website Builder for Hugo themes Customize style (CSS) To personalize Wowchemy, you can choose a colour theme and font set in config/_default/params.yaml. For further personalization, you can create your own colour theme and font theme. If advanced style customization is required, CSS code can be written to override or enhance the existing styles: Create the assets/scss/ folder if it doesn’t exist Create a file named custom.scss in the assets/scss/ folder Add your custom CSS code to the file you created and re-run Hugo to view changes --- ### Hugoにおける実行ファイルのnot foundについて date: 2021-08-31 url: https://zatoima.github.io/hugo-about-executable-not-found%20in%20Hugo/ tags: Hugo エラー 環境変数内にgoの実行ファイルが見つからないというエラーが発生する D:\hugo\zatoima.github.io>hugo server Error: failed to download modules: exec: "go": executable file not found in %PATH% 解決策 公式ドキュメントに記載があった。 Error: Go executable not found Install Hugo’s Go dependency. If you believe that Go is already installed, perhaps Hugo was unable to detect Go due to installing either Go or Hugo in an isolated way such as via Linux Snaps. Users on all major platforms have reported success installing Hugo and Go by following the official Wowchemy installation guide. You can also browse or report issues with Hugo detecting Go on the Hugo Forum. Windowsの場合は、こちらの公式ドキュメントに記載のPowerShellを実行することでエラーが解消した Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser iwr -useb get.scoop.sh | iex scoop install git go hugo-extended 実行ログ PS C:\Users\imaza> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser iwr -useb get.scoop.sh | iex Initializing... Downloading scoop... Extracting... Creating shim... Downloading main bucket... Extracting... Adding ~\scoop\shims to your path. 'lastupdate' has been set to '2021-08-23T20:01:11.4676027+09:00' Scoop was installed successfully! Type 'scoop help' for instructions. PS C:\Users\imaza> scoop install git go hugo-extended Installing '7zip' (19.00) [64bit] 7z1900-x64.msi (1.7 MB) [=====================================================================================] 100% Checking hash of 7z1900-x64.msi ... ok. Extracting 7z1900-x64.msi ... done. Linking ~\scoop\apps\7zip\current => ~\scoop\apps\7zip\19.00 Creating shim for '7z'. Creating shortcut for 7-Zip (7zFM.exe) '7zip' (19.00) was installed successfully! Installing 'git' (2.33.0.windows.1) [64bit] PortableGit-2.33.0-64-bit.7z.exe (44.1 MB) [==================================================================] 100% Checking hash of PortableGit-2.33.0-64-bit.7z.exe ... ok. Extracting dl.7z ... done. Linking ~\scoop\apps\git\current => ~\scoop\apps\git\2.33.0.windows.1 Creating shim for 'git'. Creating shim for 'gitk'. Creating shim for 'git-gui'. Creating shim for 'tig'. Creating shim for 'git-bash'. Creating shortcut for Git Bash (git-bash.exe) Creating shortcut for Git GUI (git-gui.exe) 'git' (2.33.0.windows.1) was installed successfully! Installing 'go' (1.17) [64bit] go1.17.windows-amd64.zip (143.4 MB) [=========================================================================] 100% Checking hash of go1.17.windows-amd64.zip ... ok. Extracting go1.17.windows-amd64.zip ... done. Running installer script... Linking ~\scoop\apps\go\current => ~\scoop\apps\go\1.17 Creating shim for 'go'. Creating shim for 'gofmt'. 'go' (1.17) was installed successfully! Notes ----- Your GOROOT has been set to: C:\Users\imaza\scoop\apps\go\current You can run 'go env GOROOT' to view this at any time. "$env:USERPROFILE\go\bin" has been added to your PATH. Installing 'hugo-extended' (0.87.0) [64bit] hugo_extended_0.87.0_windows-64bit.zip (16.2 MB) [============================================================] 100% Checking hash of hugo_extended_0.87.0_windows-64bit.zip ... ok. Extracting hugo_extended_0.87.0_windows-64bit.zip ... done. Linking ~\scoop\apps\hugo-extended\current => ~\scoop\apps\hugo-extended\0.87.0 Creating shim for 'hugo'. 'hugo-extended' (0.87.0) was installed successfully! PS C:\Users\imaza> --- ### Hugo wowchemy(旧Academic)におけるbuilding siteエラー date: 2021-08-30 url: https://zatoima.github.io/hugo-building-site-error-in-hugo-wowchemy/ tags: Hugo エラー Hugo wowchemyを使用しようとして、ビルドを実施したら次のエラーが発生。 D:\hugo\zatoima.github.io>hugo server hugo: downloading modules … go get: upgraded github.com/wowchemy/wowchemy-hugo-modules/wowchemy-cms/v5 v5.0.0-20210629192904-559885af86b7 => v5.0.0-20210811091031-81345fad46b5 go get: upgraded github.com/wowchemy/wowchemy-hugo-modules/wowchemy/v5 v5.0.0-20210629192904-559885af86b7 => v5.0.0-20210811091031-81345fad46b5 hugo: collected modules in 6776 ms WARN 2021/08/23 20:18:56 Module "github.com/wowchemy/wowchemy-hugo-modules/wowchemy/v5" is not compatible with this Hugo version; run "hugo mod graph" for more information. Start building sites … hugo v0.84.0-2C4689F7B windows/amd64 BuildDate=2021-06-18T17:14:27Z VendorInfo=gohugoio ERROR 2021/08/23 20:18:56 render of "home" failed: execute of template failed: template: index.html:5:3: executing "index.html" at <partial "site_head" .>: error calling partial: "C:\Users\imaza\AppData\Local\Temp\hugo_cache\modules\filecache\modules\pkg\mod\github.com\wowchemy\wowchemy-hugo-modules\wowchemy\v5@v5.0.0-20210811091031-81345fad46b5\layouts\partials\site_head.html:206:56": execute of template failed: template: partials/site_head.html:206:56: executing "partials/site_head.html" at <resources.Concat>: error calling Concat: resources in Concat must be of the same Media Type, got "text/x-scss" and "text/css" ERROR 2021/08/23 20:18:56 render of "section" failed: execute of template failed: template: section/event.html:5:3: executing "section/event.html" at <partial "site_head" .>: error calling partial: "C:\Users\imaza\AppData\Local\Temp\hugo_cache\modules\filecache\modules\pkg\mod\github.com\wowchemy\wowchemy-hugo-modules\wowchemy\v5@v5.0.0-20210811091031-81345fad46b5\layouts\partials\site_head.html:206:56": execute of template failed: template: partials/site_head.html:206:56: executing "partials/site_head.html" at <resources.Concat>: error calling Concat: resources in Concat must be of the same Media Type, got "text/x-scss" and "text/css" ERROR 2021/08/23 20:18:56 render of "page" failed: execute of template failed: template: _default/single.html:5:3: executing "_default/single.html" at <partial "site_head" .>: error calling partial: "C:\Users\imaza\AppData\Local\Temp\hugo_cache\modules\filecache\modules\pkg\mod\github.com\wowchemy\wowchemy-hugo-modules\wowchemy\v5@v5.0.0-20210811091031-81345fad46b5\layouts\partials\site_head.html:206:56": execute of template failed: template: partials/site_head.html:206:56: executing "partials/site_head.html" at <resources.Concat>: error calling Concat: resources in Concat must be of the same Media Type, got "text/x-scss" and "text/css" ERROR 2021/08/23 20:18:56 render of "page" failed: execute of template failed: template: project/single.html:5:3: executing "project/single.html" at <partial "site_head" .>: error calling partial: "C:\Users\imaza\AppData\Local\Temp\hugo_cache\modules\filecache\modules\pkg\mod\github.com\wowchemy\wowchemy-hugo-modules\wowchemy\v5@v5.0.0-20210811091031-81345fad46b5\layouts\partials\site_head.html:206:56": execute of template failed: template: partials/site_head.html:206:56: executing "partials/site_head.html" at <resources.Concat>: error calling Concat: resources in Concat must be of the same Media Type, got "text/x-scss" and "text/css" ERROR 2021/08/23 20:18:56 failed to render pages: render of "section" failed: execute of template failed: template: section/post.html:5:3: executing "section/post.html" at <partial "site_head" .>: error calling partial: "C:\Users\imaza\AppData\Local\Temp\hugo_cache\modules\filecache\modules\pkg\mod\github.com\wowchemy\wowchemy-hugo-modules\wowchemy\v5@v5.0.0-20210811091031-81345fad46b5\layouts\partials\site_head.html:206:56": execute of template failed: template: partials/site_head.html:206:56: executing "partials/site_head.html" at <resources.Concat>: error calling Concat: resources in Concat must be of the same Media Type, got "text/x-scss" and "text/css" Built in 188 ms Error: Error building site: TOCSS: failed to transform "main_parsed.scss" (text/x-scss). Check your Hugo installation; you need the extended version to build SCSS/SASS. 解決策 HugoのExtendedのバージョンを使用する必要があるという公式サイトの記事があった。 Frequently Asked Questions | Hugo https://gohugo.io/troubleshooting/faq/#i-get-tocss--this-feature-is-not-available-in-your-current-hugo-version I get “TOCSS … this feature is not available in your current Hugo version” If you process SCSS or SASS to CSS in your Hugo project, you need the Hugo extended version, or else you may see this error message: error: failed to transform resource: TOCSS: failed to transform "scss/main.scss" (text/x-scss): this feature is not available in your current Hugo version We release two set of binaries for technical reasons. The extended version is not what you get by default for some installation methods. On the release page, look for archives with extended in the name. To build hugo-extended, use go install --tags extended To confirm, run hugo version and look for the word extended. 下記から使用するバージョンのバイナリ(hugo_extended_x.xx.x_xxxx)をダウンロードして、既存のHugoのバイナリと置き換えて再ビルドを行う。 https://github.com/gohugoio/hugo/releases --- ### GCPのAssociate Cloud Engineer取得に向けた勉強方法 date: 2021-08-29 url: https://zatoima.github.io/gcp-associate-cloud-engineer-certification-prep/ tags: GCP 試験概要 Associate Cloud Engineer 認定資格 | Google Cloud https://cloud.google.com/certification/cloud-engineer 試験ガイド Associate Cloud Engineer 認定資格 | Google Cloud https://cloud.google.com/certification/guides/cloud-engineer 勉強ステップ 書籍「GCPの教科書」を読む 書籍「Google Cloud Platform エンタープライズ設計ガイド」を読む Associate Cloud Engineer 模擬試験をやってみる Qwiklabs のクエスト Google Cloud Essentials Cloud Engineering Baseline: Infrastructure Cloud Architecture Coursera Architecting with Google Compute Engine 日本語版専門講座 Google Cloud Platform Fundamentals: Core Infrastructure 日本語版 Essential Cloud Infrastructure: Foundation 日本語版 Essential Cloud Infrastructure: Core Services 日本語版 Elastic Cloud Infrastructure: Scaling and Automation 日本語版 Preparing for the Google Cloud Associate Cloud Engineer Exam Udemyの問題集をやってみる GCP Associate Cloud Engineer チートシート から関連する公式マニュアルを確認する [Master] GCP Getting Started JP GCPUG公開資料 GCPのチュートリアル Cloud OnAirでメインサービスのセッション資料を読む 追加で実施する kubernetesの勉強をする。ネットでググって雰囲気を理解 AWSのEC2上で動作させている自作アプリをAlways Freeを目当てにGCPへ移行 無料期間終わったのにも関わらずt2.nanoで動作させているEC2のインスタンス料金が響いていた BigQuery、Cloud SQL、Spannerを触って遊ぶ --- ### Excelのグラフで横軸を1時間ごとのグラフにする方法 date: 2021-08-27 url: https://zatoima.github.io/hourly-graph-for-horizontal-axis-in-excel/ tags: その他 意外とパッとわからなかったのでメモ。 ↓のようにx軸(横軸)を1時間ごとのグラフを作りたい。対象のデータ自体は全て揃っておらず、任意のタイミングでのみ取得している前提。 グラフ自体は折れ線グラフではなく散布図として、軸の書式設定の単位で1時間ごとのシリアル値を示す「0.041666666666」とする。ここのシリアル値を変更することでX軸の単位を変更することが出来る。 参考 エクセル グラフ 時間: エクセルの基本操作と小技 http://excelwaza.seesaa.net/article/371155163.html --- ### 新型コロナウイルス感染症(COVID-19) ワクチン2回目摂取の体温推移 date: 2021-08-26 url: https://zatoima.github.io/other-moderna-vaccination-2nd-log/ tags: その他 モデルナワクチン2回目の体温推移の記録。ブースター用の3回目摂取という話もあるので備忘として。想定以上に辛かった --- ### GCP BigQueryの基礎をざっくり理解する date: 2021-08-24 url: https://zatoima.github.io/gcp-bigquery-google-cloud-overview-basic/ tags: GCP, BigQuery AWSで言えば、Athenaのような、、、Redshiftのような、、、Auroraのような、、サービスと理解した BigQueryの構成要素 BigQueryマネージドストレージ スケーラブルなデータ・ストレージ BigQuery Analysis Dremelクエリエンジンテクノロジーに基づく並列SQLエンジン アーキテクチャ データ格納方式 データの分散配置 クエリの並列処理 データ型 https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types?hl=ja データの持ち方 BigQueryの場合、読み取り量に応じた課金が発生するので、積極的に使うことを検討。 パーティション分割テーブル パーティションプルーニング、パーティション単位でエクスポート等 クラスタ化テーブル クラスタリング列に基づいてデータ配置、並び順が調整 スロット 処理の並列度で、デフォルトだと2000が上限。bigqueryの並列処理の速さはストレージの分散、スロット分散で実現しているが、スロット数がこの上限までスケールするとは限らないことには注意。CPUコア数を指しているわけでは無さそう。 https://cloud.google.com/bigquery/docs/slots?hl=ja BigQuery スロットは、BigQuery で SQL クエリを実行するために使用される仮想 CPU です。BigQuery はクエリのサイズと複雑さに応じて、クエリごとに必要なスロットの数を自動的に計算します。 Google BigQuery の知らない?世界 - Qiita https://qiita.com/AkiQ/items/9c5eefb7953409aa2eda 前述しましたSlotですが、デフォルトでプロジェクトに対して最大2,000 Slot与えられます。クエリーの爆速はSlot の並列処理により生み出していると言えます。Slotは、BigQuery のその時点で余っているリソースから割り当てるわけです、考えてみたら当たり前ですけど。Slotは基本的にグローバルリソースです。 ということは、最大2,000 Slot使用できると言っていますが、使いたくても2,000 Slot同時に使用できるとは限らないのです。 BigQueryの階層構造 コスト最適化に向けて BigQuery破産という話題が以前にあったが、大容量に対しての分析クエリになる場合、コスト面を気をつける必要がある BigQuery におけるコスト最適化の ベスト プラクティス | Google Cloud Blog https://cloud.google.com/blog/ja/products/data-analytics/cost-optimization-best-practices-for-bigquery?utm_source=pocket_mylist 料金体系 料金 | BigQuery: クラウド データ ウェアハウス | Google Cloud https://cloud.google.com/bigquery/pricing?hl=ja クエリ料金 ストレージ料金 他クラウドからのデータ転送 データが無ければ分析基盤があってもどうしようも出来ない。BigQuery Data Transfer Service for Amazon S3 を使用すると、Amazon S3 から BigQuery への定期的な読み込みジョブを自動的にスケジュール出来る。もちろん逆も然り。 Amazon S3 転送 | BigQuery Data Transfer Service | Google Cloud https://cloud.google.com/bigquery-transfer/docs/s3-transfer?hl=ja 『GCPからAWSへのデータ移動』について考えて&まとめてみる | DevelopersIO https://dev.classmethod.jp/articles/data-migration-from-gcp-to-aws-matome/#a-4 参考 BigQuery ドキュメント | Google Cloud https://cloud.google.com/bigquery/docs --- ### Redshift Spectrumのパフォーマンス確認 date: 2021-08-20 url: https://zatoima.github.io/aws-redshift-spectrum-performance-check/ tags: AWS, Redshift テストクエリ \timing SET enable_result_cache_for_session = off; select d_year, s_city, p_brand1, sum(lo_revenue - lo_supplycost) as profit from s3.dwdate, s3.customer, s3.supplier, s3.part, s3.lineorder where lo_custkey = c_custkey and lo_suppkey = s_suppkey and lo_partkey = p_partkey and lo_orderdate = d_datekey and c_region = 'AMERICA' and s_nation = 'UNITED STATES' and (d_year = 1997 or d_year = 1998) and p_category = 'MFGR#14' group by d_year, s_city, p_brand1 order by d_year, s_city, p_brand1 LIMIT 10; 実行時間、実行結果 1分20秒程度掛かった mydb=# select d_year, s_city, p_brand1, sum(lo_revenue - lo_supplycost) as profit mydb-# from s3.dwdate, s3.customer, s3.supplier, s3.part, s3.lineorder mydb-# where lo_custkey = c_custkey mydb-# and lo_suppkey = s_suppkey mydb-# and lo_partkey = p_partkey mydb-# and lo_orderdate = d_datekey mydb-# and c_region = 'AMERICA' mydb-# and s_nation = 'UNITED STATES' mydb-# and (d_year = 1997 or d_year = 1998) mydb-# and p_category = 'MFGR#14' mydb-# group by d_year, s_city, p_brand1 order by d_year, s_city, p_brand1 mydb-# LIMIT 10; d_year | s_city | p_brand1 | profit --------+------------+-----------+----------- 1997 | UNITED ST0 | MFGR#141 | 262922467 1997 | UNITED ST0 | MFGR#1410 | 179590048 1997 | UNITED ST0 | MFGR#1411 | 215249314 1997 | UNITED ST0 | MFGR#1412 | 164321123 1997 | UNITED ST0 | MFGR#1413 | 175368488 1997 | UNITED ST0 | MFGR#1414 | 215494333 1997 | UNITED ST0 | MFGR#1415 | 148209735 1997 | UNITED ST0 | MFGR#1416 | 198091798 1997 | UNITED ST0 | MFGR#1417 | 176595141 1997 | UNITED ST0 | MFGR#1418 | 194768567 (10 rows) Time: 80526.072 ms (01:20.526) mydb=# SVL_S3QUERY_SUMMARY テーブルの確認 テーブルには過去のクエリ実行の実際の統計が格納されるので、そこで時間が掛かったのかを知ることが出来る select elapsed, s3_scanned_rows, s3_scanned_bytes, s3query_returned_rows, s3query_returned_bytes, files, avg_request_parallelism from svl_s3query_summary where query = pg_last_query_id() order by query,segment; mydb=# select elapsed, s3_scanned_rows, s3_scanned_bytes, mydb-# s3query_returned_rows, s3query_returned_bytes, files, avg_request_parallelism mydb-# from svl_s3query_summary mydb-# where query = pg_last_query_id() mydb-# order by query,segment; elapsed | s3_scanned_rows | s3_scanned_bytes | s3query_returned_rows | s3query_returned_bytes | files | avg_request_parallelism ----------+-----------------+------------------+-----------------------+------------------------+-------+------------------------- 269908 | 2556 | 25239 | 729 | 1830 | 1 | 0.1 1272336 | 1000000 | 34110277 | 39991 | 141551 | 4 | 0.5 2847076 | 3000000 | 105338147 | 599689 | 1748517 | 1 | 0.1 800323 | 1400000 | 34724133 | 55855 | 266349 | 4 | 0.4 73152028 | 600037902 | 26972503425 | 234982 | 3906264 | 8 | 0.8 (5 rows) Time: 558.935 ms --- ### Alexaのぴよログスキルの音声入力エラーに対して定型アクションで対応する date: 2021-08-18 url: https://zatoima.github.io/alexa-change-word-voice-control-piyolog/ tags: Alexa ここ最近、初めての育児に奮闘中です。Alexa経由でぴよログを使用して育児記録、育児ログを使っており、妻も含めて大変好評です。導入する前はスマホを起動して記録して、、、ということをやっていました。この記録操作がめんどくさいのに加えて、記録を忘れて怒られがちということが頻発したので、Alexa経由でぴよログをつけることにしました。(見つけたときは感動した…!) https://www.amazon.co.jp/PiyoLog-Inc-%E3%81%B4%E3%82%88%E3%83%AD%E3%82%B0/dp/B08KFD3FWF ただ一点だけ問題がありました。大変素晴らしいスキルなのですが、レビューにも記載されている通り、一部操作の音声入力がうまくいかないケースがありました。頻発というほどでもないですが、5回に1回くらい発生してしまうというレベルです。具体的にはレビューの下記の事象です。 「アレクサ、ぴよログでおしっこを記録して」とテンプレワードを唱えても記録できるケースがかなり稀。大体のケースは、「ぴよログです。ミルクや睡眠、排泄などの記録と確認ができます。何を記録しますか?」と聞き返されて仕方なく「おしっこ」ともう一度言う必要があるので手間が倍かかることになります。 寝起きの夜中の4時とかにミスられるとストレス値が倍増するのでどうにか改善したいと思って定型アクションを使って文章のシノニム(別名)を設定することにしました。Alexaを使った音声操作の文言を変更したい場合は定型アクションを使うのが簡単です。 右下の「その他」を選択 「定型アクション」を選択 右上の「+」ボタンをクリック 「定型アクション名」、「実行条件」、「アクション」を指定する。「定型アクション名」は任意なので省略 実行条件は「音声」を選択する。次の画面にて起動する際のフレーズを入力する。 「アクション」ではAlexaに入力するフレーズをここに記載する ここまで設定することで、Alexaに対しておしっこというだけで「ぴよログでおしっこを記録して」と同じような内容となります。フレーズが短いのでAlexa側で他の言葉に間違えられることも無いので大変便利になりました。あとは他にどんなフレーズをいうか洗い出して同じ操作で定型アクションを作っていくことで、「おしっこ」、「お風呂」等の短いフレーズでぴよログにログを残せるようになりました。 アレクサとぴよログよありがとう! --- ### PostgreSQLのSQL実行計画の可視化(pev、gocmdpev) date: 2021-08-08 url: https://zatoima.github.io/aws-postgresql-execute-plan-visualization/ tags: AWS, PostgreSQL まずはgocmdpevを使ってみる goをインストール [ec2-user@bastin ~]$ sudo yum -y install go Loaded plugins: langpacks, priorities, update-motd amzn2-core | 3.7 kB 00:00:00 228 packages excluded due to repository priority protections Resolving Dependencies --> Running transaction check ~省略~ Installed: golang.x86_64 0:1.15.14-1.amzn2.0.1 Dependency Installed: apr.x86_64 0:1.6.3-5.amzn2.0.2 apr-util.x86_64 0:1.6.1-5.amzn2.0.2 apr-util-bdb.x86_64 0:1.6.1-5.amzn2.0.2 golang-bin.x86_64 0:1.15.14-1.amzn2.0.1 golang-src.noarch 0:1.15.14-1.amzn2.0.1 mercurial.x86_64 0:2.6.2-10.amzn2 neon.x86_64 0:0.30.0-3.amzn2.0.2 pakchois.x86_64 0:0.4-10.amzn2.0.2 subversion.x86_64 0:1.7.14-16.amzn2.0.1 subversion-libs.x86_64 0:1.7.14-16.amzn2.0.1 Complete! [ec2-user@bastin ~]$ [ec2-user@bastin ~]$ go version go version go1.15.14 linux/amd64 [ec2-user@bastin ~]$ go get -u github.com/simon-engledew/gocmdpev [ec2-user@bastin ~]$ echo $? 0 [ec2-user@bastin ~]$ ./go/bin/gocmdpev --version 1.0.0 可視化のためのテスト用のデータ生成 pgbench -i -s 100 -U postgres -h xxxx.cluster-xxxx.ap-northeast-1.rds.amazonaws.com pgbench テスト用のSQL EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSON) SELECT t1.aid,t1.bid,t1.abalance,t2.bbalance FROM pgbench_accounts t1, pgbench_branches t2 where t1.bid=t2.bid ORDER BY t1.abalance DESC; こんな感じのSQLになります。ソートやジョイン等で問題がありそうなSQLとなっている FORMAT指定等があり、gocmdpevに渡すための実行計画を生成する。 vi explain.sql 下記SQLをexplain.sqlに記載する。ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSONをEXPLAINのオプションに指定する EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSON) SELECT t1.aid,t1.bid,t1.abalance,t2.bbalance FROM pgbench_accounts t1, pgbench_branches t2 where t1.bid=t2.bid ORDER BY t1.abalance DESC; SQLを実行して実行計画をanalyze.jsonに出力する psql -h auroraserverlessv1.cluster-cm678nkt5thr.ap-northeast-1.rds.amazonaws.com -U postgres -d pgbench -qAt -f explain.sql > analyze.json 出力されたanalyze.jsonをgocmdpevに渡す cat analyze.json | gocmdpev 下記のような出力となる。どこに時間が掛かっているか等が色付きで表示されるので、解析しやすくなる。 [ec2-user@bastin ~]$ cat analyze.json | gocmdpev ○ Total Cost: 1,790,852.84 ○ Planning Time: 53.45 ms ○ Execution Time: 7.92 s ┬ │ └─⌠ Gather Merge costliest largest │ │ ○ Duration: 2.03 s (26%) │ ○ Cost: 962,873.54 (54%) │ ○ Rows: 10,000,000 │ rows Underestimated by 1.20x ├► t1.aid + t1.bid + t1.abalance + t2.bbalance │ └─⌠ Sort slowest │ Sorts a record set based on the specified sort key. │ ○ Duration: 6.60 s (83%) │ ○ Cost: 610,973.3400000001 (34%) │ ○ Rows: 3,333,333 │ rows Overestimated by 1.25x ├► t1.aid + t1.bid + t1.abalance + t2.bbalance │ └─⌠ Hash Join │ Joins to record sets by hashing one of them (using │ a Hash Scan). │ ○ Duration: 4.88 s (62%) │ ○ Cost: 11,402.289999999979 (1%) │ ○ Rows: 3,333,333 │ Inner join │ on (t1.bid = t2.bid) │ rows Overestimated by 1.25x ├► t1.aid + t1.bid + t1.abalance + t2.bbalance │ ├─⌠ Seq Scan │ │ Finds relevant records by sequentially │ │ scanning the input record set. When reading │ │ from a table, Seq Scans (unlike Index Scans) │ │ perform a single read operation (only the │ │ table is read). │ │ ○ Duration: 5.12 s (65%) │ │ ○ Cost: 205,601.67 (11%) │ │ ○ Rows: 3,333,333 │ │ on public.pgbench_accounts │ │ rows Overestimated by 1.25x │ ⌡► t1.aid + t1.bid + t1.abalance │ └─⌠ Hash │ Generates a hash table from the records in the │ input recordset. Hash is used by Hash Join. │ ○ Duration: <1 ms (0%) │ ○ Cost: 0 (0%) │ ○ Rows: 100 ├► t2.bbalance + t2.bid │ └─⌠ Seq Scan │ Finds relevant records by sequentially │ scanning the input record set. When reading │ from a table, Seq Scans (unlike Index Scans) │ perform a single read operation (only the │ table is read). │ ○ Duration: <1 ms (0%) │ ○ Cost: 2 (0%) │ ○ Rows: 100 │ on public.pgbench_branches ⌡► t2.bbalance + t2.bid pevという実行計画の可視化ツールもある。こちらの方が直感的で見やすいかもしれない。CLIで確認したいのかGUIベースで確認したいのかで使い分けても良い。gocmdpevと同じでANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSONを読み込ませることで可視化が出来る。 https://github.com/AlexTatiyants/pev http://tatiyants.com/pev/#/plans/new 下記の通り、ローカルで処理すると記載はしているが念の為に用心した方が良いかもしれない DISCLAIMER: Pev stores your plans locally (localStorage) and will not send them anywhere. pev, gocmdpevでPostgreSQLのEXPLAINを見やすくする | gocmdpev https://wonderwall.hatenablog.com/entry/2017/09/13/220000 --- ### Aurora PostgreSQL を AWS CLIで作成 date: 2021-07-26 url: https://zatoima.github.io/aws-aurora-aws-cli-create-cluster-instance/ tags: AWS, Aurora create-db-cluster → create-db-instanceで作成の流れな模様。1コマンドでは実行出来ないようなので複数回実行する必要がある。 クラスタ作成 aws rds create-db-cluster \ --db-cluster-identifier aurorapgsqlv1-cluster1 \ --engine aurora-postgresql \ --engine-version 11.9 \ --master-username postgres \ --master-user-password postgres \ --db-subnet-group-name devvpc-db-sub-pvt \ --vpc-security-group-ids sg-01f24d968d81d144a \ --availability-zones "ap-northeast-1a" "ap-northeast-1c" "ap-northeast-1d" \ --port 5432 \ --database-name postgres create-db-cluster — AWS CLI1.20.3コマンドリファレンス https://docs.aws.amazon.com/cli/latest/reference/rds/create-db-cluster.html インスタンス作成 aws rds create-db-instance \ --db-instance-identifier aurorapgsqlv1-instance1 \ --db-instance-class db.r5.large \ --engine aurora-postgresql \ --engine-version 11.9 \ --availability-zone "ap-northeast-1c" \ --db-cluster-identifier aurorapgsqlv1-cluster1 \ --db-parameter-group-name aurora-pgsql11 リードレプリカを作成する際にはもう一度同じコマンドを実行 aws rds create-db-instance \ --db-instance-identifier aurorapgsqlv1-instance2 \ --db-instance-class db.r5.large \ --engine aurora-postgresql \ --engine-version 11.9 \ --availability-zone "ap-northeast-1d" \ --db-cluster-identifier aurorapgsqlv1-cluster1 \ --db-parameter-group-name aurora-pgsql11 create-db-instance — AWS CLI 1.20.3 Command Reference https://docs.aws.amazon.com/cli/latest/reference/rds/create-db-instance.html 結果 下記の通り、マネージドメントコンソール上からも確認が出来た。 --- ### AthenaをCLIベースで実行する(AWS CLI、athenacli) date: 2021-07-21 url: https://zatoima.github.io/aws-athena-cli-query-execute/ tags: AWS, Athena s3_spectrumというデータベースを対象にAthenaのクエリを実行していく。(このデータベースはredshift spectrumの検証時に作ったデータベースの使い回し) AWS CLI AWS CLIの場合は、start-query-executionで実行してクエリ実行IDを取得して別のAPIで結果を確認ということになる。(ややこしい) start-query-execution aws athena start-query-execution --query-string "select * from supplier limit 2;" --query-execution-context Database=s3_spectrum --result-configuration OutputLocation=s3://xxxx/ get-query-execution aws athena get-query-execution --query-execution-id 16751da3-a267-4958-91dd-678c02d2af26 get-query-results aws athena get-query-results --query-execution-id 16751da3-a267-4958-91dd-678c02d2af26 実行結果 get-query-resultsではJSON形式で出力されるので、必要に応じてjqコマンドで整形するか、S3側に出力されるCSVデータをダウンロードして確認する方法が良いかもしれない。 [ec2-user@ip-10-0-1-31 ~]$ aws athena start-query-execution --query-string "select * from supplier limit 2;" --query-execution-context Database=s3_spectrum --result-configuration OutputLocation=s3://xxxx/ { "QueryExecutionId": "16751da3-a267-4958-91dd-678c02d2af26" } [ec2-user@ip-10-0-1-31 ~]$ aws athena get-query-execution --query-execution-id 16751da3-a267-4958-91dd-678c02d2af26 { "QueryExecution": { "QueryExecutionId": "16751da3-a267-4958-91dd-678c02d2af26", "Query": "select * from supplier limit 2", "StatementType": "DML", "ResultConfiguration": { "OutputLocation": "s3://xxxx/16751da3-a267-4958-91dd-678c02d2af26.csv" }, "QueryExecutionContext": { "Database": "s3_spectrum" }, "Status": { "State": "SUCCEEDED", "SubmissionDateTime": 1625791317.39, "CompletionDateTime": 1625791318.366 }, "Statistics": { "EngineExecutionTimeInMillis": 761, "DataScannedInBytes": 332580, "TotalExecutionTimeInMillis": 976, "QueryQueueTimeInMillis": 191, "QueryPlanningTimeInMillis": 89, "ServiceProcessingTimeInMillis": 24 }, "WorkGroup": "primary" } } [ec2-user@ip-10-0-1-31 ~]$ aws athena get-query-results --query-execution-id 16751da3-a267-4958-91dd-678c02d2af26 { "ResultSet": { "Rows": [ { "Data": [ { "VarCharValue": "s_suppkey" }, { "VarCharValue": "s_name" }, ~省略~ }, "UpdateCount": 0 } athenacli AthenaCLIはAthenaサービス用のコマンドラインインターフェース(CLI)で、自動補完やシンタックスハイライトを行うことができ、postgresqlやmysql用のCLIと同じようなもの。AWS CLIのように何度もAWS CLIを叩かなくて1度のクエリで結果までCSV形式(もしくは見やすい形式)で見れる。 athenacliのインストール pip install athenacli 設定ファイルの編集 設定ファイルは~/.athenacli/athenaclircにあるので編集する vi ~/.athenacli/athenaclirc Regionとs3_staging_dirだけ定義。IAMロールで実行しているため、アクセスキー等は省略 [aws_profile default] # If you are a user of aws cli, you might want to use some configurations of aws cli, # please refer to https://athenacli.readthedocs.io/en/latest/awsconfig.html for more infomation. aws_access_key_id = '' aws_secret_access_key = '' region = 'ap-northeast-1' # e.g us-west-2, us-east-1 # Add role_arn to assume a role required for Athena access role_arn = '' # e.g. arn:aws:iam::987654321000:role/MyAthenaAccessRole # Amazon S3 staging directory where query results are stored # NOTE: S3 should in the same region as specified above. # The format is 's3://<your s3 directory path>' s3_staging_dir = 's3://athenadatacsv/' # Name of athena workgroup that you want to use work_group = 'primary' # e.g. primary ~中略~ 環境変数を使っても実行は出来る。 export AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY_ID export AWS_SECRET_ACCESS_KEY=YOUR_SECRET_ACCESS_KEY export AWS_DEFAULT_REGION=ap-northeast-1 export AWS_ATHENA_S3_STAGING_DIR=s3://YOUR_S3_BUCKET/path/to/ 実行 引数にSQLを渡して実行するパターン [ec2-user@ip-10-0-1-31 .athenacli]$ athenacli s3_spectrum -e 'select * from supplier limit 2' s_suppkey,s_name,s_address,s_city,s_nation,s_region,s_phone 1,Supplier#000000001," N kD4on9OM Ipw3,gf0J",PERU 0,PERU,AMERICA,27-989-741-2988 2,Supplier#000000002,89eJ5ksX3Imx,ETHIOPIA 1,ETHIOPIA,AFRICA,15-768-687-3665 [ec2-user@ip-10-0-1-31 .athenacli]$ コマンドライン上で実行するパターン [ec2-user@ip-10-0-1-31 .athenacli]$ athenacli s3_spectrum ap-northeast-1:s3_spectrum> select * from supplier limit 2; +-----------+--------------------+-----------------------+------------+----------+----------+-----------------+ | s_suppkey | s_name | s_address | s_city | s_nation | s_region | s_phone | +-----------+--------------------+-----------------------+------------+----------+----------+-----------------+ | 1 | Supplier#000000001 | N kD4on9OM Ipw3,gf0J | PERU 0 | PERU | AMERICA | 27-989-741-2988 | | 2 | Supplier#000000002 | 89eJ5ksX3Imx | ETHIOPIA 1 | ETHIOPIA | AFRICA | 15-768-687-3665 | +-----------+--------------------+-----------------------+------------+----------+----------+-----------------+ 2 rows in set Execution time: 773 ms, Data scanned: 320.58 KB, Approximate cost: $0.00 Time: 1.349s ap-northeast-1:s3_spectrum> 細かい実行時の設定はgithub上のreadmeを参照。 https://github.com/dbcli/athenacli 参考 [dbcli/athenacli: AthenaCLI is a CLI tool for AWS Athena service that can do auto-completion and syntax highlighting.](dbcli/athenacli: AthenaCLI is a CLI tool for AWS Athena service that can do auto-completion and syntax highlighting. ) Very cool らしい AthenaCLI を試してみたら、やっぱりクールだった件 | DevelopersIO --- ### AWSの使用料をPythonでLINEに通知する date: 2021-07-14 url: https://zatoima.github.io/aws-python-amount-to-use-cost-line-notify/ tags: AWS, python 前提 Line Notifyの設定が完了していること(https://notify-bot.line.me/ja/) CloudWatchの権限が付与されていて、AWS CLIの実行が可能なこと コード ほぼ他で作ったスクリプトの使いまわし… import os,sys,datetime import boto3 import requests import datetime def main(): get_aws_cost() send_line_notify(LINE_TEXT) def send_line_notify(notification_message): line_notify_token = 'xxxxxxxxxxxxxxxxxxxxxxx' line_notify_api = 'https://notify-api.line.me/api/notify' headers = {'Authorization': f'Bearer {line_notify_token}'} data = {'message': f'message: {notification_message}'} requests.post(line_notify_api, headers = headers, data = data) def get_aws_cost(): AWS_REGION = "us-east-1" response = boto3.client('cloudwatch', region_name='us-east-1') today_date = datetime.date.today().strftime('%Y/%m/%d') def get_value(): get_demesion = [{'Name': 'Currency', 'Value': 'USD'}] data = response.get_metric_statistics( Namespace='AWS/Billing', MetricName='EstimatedCharges', Period=86400, StartTime=today_date + " 00:00:00", EndTime=today_date + " 23:59:59", Statistics=['Maximum'], Dimensions=get_demesion ) for info in data['Datapoints']: return info['Maximum'] total_value = get_value() global LINE_TEXT LINE_TEXT='本日までのAWSの利用料金は$' + str(total_value) + 'になります' if __name__ == "__main__": main() --- ### PostgreSQLの拡張機能 pg_proctab をAurora/RDSから触ってみる date: 2021-07-12 url: https://zatoima.github.io/aws-aurora-rds-postgresql-pg_proctab-extention/ tags: AWS, Aurora, RDS, PostgreSQL Aurora、及びRDS PostgreSQLでサポートされたpg_proctabについてざっと触ってみる。 開発側のリポジトリはこちら。 pg_proctab / pg_proctab · GitLab https://gitlab.com/pg_proctab/pg_proctab PostgreSQL extension to access the operating system process table.とあるようにPostgreSQLからOS関連の情報を取得出来る関数が提供される模様。 AuroraやRDSの場合、従来であればモニタリングのOSプロセスリストから確認が可能だったが、PostgreSQL側のSQLベースでも確認が可能になった。 pg_proctab create extension pg_proctab; \dx 追加されるファンクション select * from pg_cputime(); select * from pg_loadavg(); select * from pg_memusage(); select * from pg_proctab(); 実行結果 postgres=> create extension pg_proctab; CREATE EXTENSION postgres=> postgres=> \dx List of installed extensions Name | Version | Schema | Description ------------+---------+------------+--------------------------------------- pg_proctab | 0.0.9 | public | Access operating system process table plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language (2 rows) pg_cputime postgres=> select * from pg_cputime(); user | nice | system | idle | iowait -------+------+--------+--------+-------- 28387 | 5841 | 14782 | 362592 | 3942 (1 row) user: normal processes executing in user mode nice: niced processes executing in user mode system: processes executing in kernel mode idle: processes twiddling thumbs iowait: waiting for I/O to complete pg_loadavg postgres=> select * from pg_loadavg(); load1 | load5 | load15 | last_pid -------+-------+--------+---------- 23.92 | 5.71 | 2.02 | 30030 (1 row) load1: load average of last minute load5: load average of last 5 minutes load15: load average of last 15 minutes last pid: last pid running pg_memusage postgres=> select * from pg_memusage(); memused | memfree | memshared | membuffers | memcached | swapused | swapfree | swapcached ----------+---------+-----------+------------+-----------+----------+----------+------------ 12767552 | 3357416 | 0 | 62624 | 476284 | 0 | 8384508 | 0 (1 row) memused: Total physical RAM used memfree: Total physical RAM not used memshared: Not used, always 0. (For Solaris.) membuffers: Temporary storage for raw disk blocks memcached: In-memory cache for files read from disk swapused: Total swap space used swapfree: Memory evicted from RAM that is now temporary on disk swapcached: Memory that was swapped out, now swapped in but still in swap pg_proctab postgres=> select * from pg_proctab(); pid | comm | fullcomm | state | ppid | pgrp | session | tty_nr | tpgid | flags | minflt | cminflt | majflt | cmajflt | utime | stime | cutime | cstime | priority | nice | num_threads | itrealvalue | starttime | vsize | rss | exit_signal | processor | rt_priority | policy | delayacct_blkio_ticks | uid | username | rchar | wchar | syscr | syscw | reads | writes | cwrites -------+------+------------------------------------------------------------------+-------+------+------+---------+--------+-------+-------+--------+---------+--------+---------+-------+-------+--------+--------+----------+------+-------------+-------------+-----------+-------------+--------+-------------+---------- -+-------------+--------+-----------------------+-----+----------+---------+-------+-------+-------+--------+--------+--------- 9811 | | postgres: autovacuum launcher | S | 9657 | | 9811 | 0 | -1 | | 4253 | 0 | 2 | 0 | 10 | 20 | 0 | 0 | 39 | 19 | 1 | 0 | 18573 | 22007947264 | 11400 | 17 | | 0 | 0 | 0 | | | 5641788 | 3309 | 6468 | 2592 | 172032 | 0 | 0 9813 | | postgres: logical replication launcher | S | 9657 | | 9813 | 0 | -1 | | 368 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 39 | 19 | 1 | 0 | 18573 | 22003752960 | 11380 | 17 | | 0 | 0 | 0 | | | 95979 | 726 | 37 | 9 | 454656 | 0 | 0 15233 | | postgres: rdsadmin rdsadmin [local] idle | S | 9657 | | 15233 | 0 | -1 | | 638 | 0 | 0 | 0 | 10 | 3 | 0 | 0 | 39 | 19 | 1 | 0 | 28599 | 22114021376 | 17424 | 17 | | 0 | 0 | 0 | | | 237463 | 3 | 71 | 3 | 0 | 0 | 0 15237 | | postgres: rdsadmin rdsadmin [local] idle | S | 9657 | | 15237 | 0 | -1 | | 851 | 0 | 0 | 0 | 53 | 10 | 0 | 0 | 39 | 19 | 1 | 0 | 28630 | 22114021376 | 24048 | 17 | | 0 | 0 | 0 | | | 237463 | 323 | 71 | 6 | 0 | 0 | 0 15757 | | postgres: rdsadmin rdsadmin [local] idle | S | 9657 | | 15757 | 0 | -1 | | 19169 | 0 | 0 | 0 | 17 | 6 | 0 | 0 | 39 | 19 | 1 | 0 | 30067 | 22126604288 | 23096 | 17 | | 0 | 0 | 0 | | | 2345107 | 13309 | 685 | 413 | 57344 | 110592 | 0 17262 | | postgres: rdsadmin rdsadmin [local] idle | S | 9657 | | 17262 | 0 | -1 | | 1940 | 0 | 0 | 0 | 15 | 2 | 0 | 0 | 39 | 19 | 1 | 0 | 33822 | 22122409984 | 19852 | 17 | | 0 | 0 | 0 | | | 2407474 | 1764 | 829 | 9 | 0 | 12288 | 0 1595 | | postgres: postgres pgbench 10.0.1.123(40590) idle | R | 9657 | | 1595 | 0 | -1 | | 950 | 0 | 0 | 0 | 122 | 34 | 0 | 0 | 39 | 19 | 1 | 0 | 215465 | 22114021376 | 24360 | 17 | | 0 | 0 | 0 | | | 173522 | 350 | 100 | 55 | 0 | 0 | 0 12743 | | postgres: postgres postgres 10.0.1.123(40258) SELECT | R | 9657 | | 12743 | 0 | -1 | | 2432 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 39 | 19 | 1 | 0 | 168728 | 22122459136 | 24668 | 17 | | 0 | 0 | 0 | | | 272234 | 1181 | 556 | 9 | 0 | 4096 | 0 1599 | | postgres: postgres pgbench 10.0.1.123(40598) idle in transaction | R | 9657 | | 1599 | 0 | -1 | | 981 | 0 | 0 | 0 | 124 | 34 | 0 | 0 | 39 | 19 | 1 | 0 | 215465 | 22114021376 | 24636 | 17 | | 0 | 0 | 0 | | | 173515 | 47 | 93 | 47 | 0 | 0 | 0 1596 | | postgres: postgres pgbench 10.0.1.123(40592) UPDATE | R | 9657 | | 1596 | 0 | -1 | | 941 | 0 | 0 | 0 | 119 | 38 | 0 | 0 | 39 | 19 | 1 | 0 | 215465 | 22114021376 | 24688 | 17 | | 0 | 0 | 0 | | | 173522 | 54 | 100 | 54 | 0 | 0 | 0 1597 | | postgres: postgres pgbench 10.0.1.123(40594) COMMIT | S | 9657 | | 1597 | 0 | -1 | | 940 | 0 | 0 | 0 | 123 | 39 | 0 | 0 | 39 | 19 | 1 | 0 | 215465 | 22114021376 | 24452 | 17 | | 0 | 0 | 0 | | | 173512 | 340 | 90 | 45 | 0 | 0 | 0 1598 | | postgres: postgres pgbench 10.0.1.123(40596) idle in transaction | R | 9657 | | 1598 | 0 | -1 | | 948 | 0 | 0 | 0 | 124 | 36 | 0 | 0 | 39 | 19 | 1 | 0 | 215465 | 22114021376 | 24628 | 17 | | 0 | 0 | 0 | | | 173512 | 44 | 90 | 44 | 0 | 0 | 0 9809 | | postgres: background writer | S | 9657 | | 9809 | 0 | -1 | | 230 | 0 | 0 | 0 | 1 | 2 | 0 | 0 | 39 | 19 | 1 | 0 | 18573 | 22003752960 | 7892 | 17 | | 0 | 0 | 0 | | | 96446 | 1193 | 504 | 476 | 0 | 0 | 0 9808 | | postgres: checkpointer | S | 9657 | | 9808 | 0 | -1 | | 341 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 39 | 19 | 1 | 0 | 18573 | 22003752960 | 10144 | 17 | | 0 | 0 | 0 | | | 95981 | 10792 | 39 | 45 | 0 | 0 | 0 9810 | | postgres: walwriter | S | 9657 | | 9810 | 0 | -1 | | 210 | 0 | 0 | 0 | 5 | 16 | 0 | 0 | 39 | 19 | 1 | 0 | 18573 | 22003752960 | 7408 | 17 | | 0 | 0 | 0 | | | 96014 | 761 | 72 | 44 | 0 | 0 | 0 9741 | | postgres: aurora runtime process | S | 9657 | | 9741 | 0 | -1 | | 7252 | 0 | 2 | 0 | 300 | 166 | 0 | 0 | 20 | 0 | 12 | 0 | 18453 | 22072946688 | 183176 | 17 | | 0 | 0 | 0 | | | 130184 | 845 | 2023 | 11 | 266240 | 0 | 0 9815 | | postgres: aurora resource monitoring process | S | 9657 | | 9815 | 0 | -1 | | 1826 | 0 | 0 | 0 | 7 | 3 | 0 | 0 | 39 | 19 | 1 | 0 | 18573 | 22003752960 | 12252 | 17 | | 0 | 0 | 0 | | | 922456 | 726 | 2021 | 9 | 0 | 0 | 0 (17 rows) 参考 pg_proctab: Accessing System Stats in PostgreSQL --- ### 複数の画像ファイルを一つのPDFにするPythonスクリプト date: 2021-07-09 url: https://zatoima.github.io/python-multiple-img-to-pdf/ tags: python ライブラリのインストール pip install img2pdf スクリプト 拡張子をpngで指定しているが、jpgに変えれば動く。 import os import img2pdf from PIL import Image if __name__ == '__main__': print('画像を結合したい対象ディレクトリを入力してください') img_Folder = input('>> ') #末尾のスラッシュ有無を確認し、スラッシュを付与 if(img_Folder[-1:]!="\\"): img_Folder=img_Folder + '\\' print(img_Folder) pdf_FileName = img_Folder + 'output.pdf' # 出力するPDFの名前 extension = ".png" with open(pdf_FileName,"wb") as f: f.write(img2pdf.convert([Image.open(img_Folder+j).filename for j in os.listdir(img_Folder)if j.endswith(extension)])) --- ### Redshiftのクエリキャンセル date: 2021-07-06 url: https://zatoima.github.io/aws-redshift-query-cancellation/ tags: AWS, Redshift PIDの取得 select pid, trim(starttime) as start, duration, trim(user_name) as user,substring (query,1,40) as querytxt from stv_recents where status = 'Running'; PIDのkill select pg_cancel_backend(16749); もしくは cancel 16749; 実行クライアント側にはエラーメッセージが出力される client 2 aborted in command 16 (SQL) of script 0; ERROR: Query (570) cancelled on user's request https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_CANCEL.html https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/PG_CANCEL_BACKEND.html --- ### RDS OracleにJDBCRunnerを実行 date: 2021-07-01 url: https://zatoima.github.io/oracle-rds-jdbcrunner/ tags: AWS, RDS, Oracle 概要図 図にするまでも無かったが、EC2上に配置したjdbcRunnerからRDS Oracle SE2に対してTPC-Cベースの負荷掛けを実施 jdbcRunnerを使用した負荷テストの流れや構成、動作については下記参照 https://dbstudy.info/jdbcrunner/docs_ja/procedure.html jdbcRunnerのダウンロード 下記からjdbcrunner-1.3.zipをダウンロードしてEC2にアップロードする。 https://dbstudy.info/jdbcrunner/ jdbcRunnerのセットアップ、事前準備 javaのインストール sudo yum -y install java-1.8.0-openjdk.x86_64 jdbcrunnerの配置 unzip jdbcrunner-1.3.zip cd jdbcrunner-1.3 クラスパスの設定 export CLASSPATH=/home/ec2-user/jdbcrunner-1.3/jdbcrunner-1.3.jar:/usr/lib/oracle/18.3/client64/lib/ojdbc8.jar tnsnames.oraの確認 適切に設定されていること cat $ORACLE_HOME/network/admin/tnsnames.ora スクリプトの修正 cd /home/ec2-user/jdbcrunner-1.3/scripts vi tpcc_load.js vi tpcc.js 既存のjdbcurlを下記の通り修正 #var jdbcUrl = "jdbc:oracle:thin:@//サーバのパブリックIPアドレス:1521/サービス名"; var jdbcUrl = "jdbc:oracle:thin:@//ora19c-se2.xxxxx.ap-northeast-1.rds.amazonaws.com:1521/ora19c"; 実行ユーザの作成 sqlplus oracle@ora19c drop user tpcc cascade; drop tablespace tpcc; create tablespace tpcc datafile autoextend on next 1g maxsize unlimited; CREATE USER tpcc DEFAULT TABLESPACE tpcc IDENTIFIED BY tpcc; GRANT CREATE SESSION, CREATE TABLE, UNLIMITED TABLESPACE TO tpcc; jadcRunnerの実行 テストデータのロード cd /home/ec2-user/jdbcrunner-1.3/scripts java JR tpcc_load.js スケールファクターを指定しないデフォルトだとざっくりと1.5GB程度データが入る模様 NAME STATUS TYPE EXTMGT ALLOC INIT_KB SEGMGT USED(MB) TOTAL(MB) USED(% --------------- --------- --------------------- ---------- --------- ---------- ------ ------------ ------------ ------ RDSADMIN ONLINE PERMANENT LOCAL SYSTEM 64 AUTO 6.5 7.0 92.9 SYSAUX ONLINE PERMANENT LOCAL SYSTEM 64 AUTO 375.7 400.0 93.9 SYSTEM ONLINE PERMANENT LOCAL SYSTEM 64 MANUAL 493.7 500.0 98.7 TEMP ONLINE TEMPORARY LOCAL UNIFORM 1024 MANUAL 164.0 200.0 82.0 TPCC ONLINE PERMANENT LOCAL SYSTEM 64 AUTO 1,527.3 2,148.0 71.1 UNDO_T1 ONLINE UNDO LOCAL SYSTEM 64 MANUAL 2,421.0 2,430.0 99.6 USERS ONLINE PERMANENT LOCAL SYSTEM 64 AUTO 68.1 1,980.6 3.4 7 rows selected. スケールファクターを指定する場合は下記を参照。 https://dbstudy.info/jdbcrunner/docs_ja/tpc-c.html -param0を指定することによって、スケールファクタを変更することが可能です。スケールファクタ1あたりwarehouseテーブルのレコード数が1増加し、その他のテーブルについてもレコード数が以下のように増加します。デフォルトのスケールファクタは16です。 Table Records warehouse sf x 1 district sf x 10 customer sf x 30,000 history sf x 30,000 item 100,000 stock sf x 100,000 orders sf x 30,000 new_orders sf x 9,000 order_line sf x 300,000 (approx.) 下記の例だと8並列でデータロードを実行して、スケールファクターは100となる。デフォルトと比べると約5倍のデータ量となる(はず) java JR tpcc_load.js -nAgents 8 -param0 100 負荷テスト cd /home/ec2-user/jdbcrunner-1.3/scripts java -server JR tpcc.js 動作を変更したい場合は下記を参照しつつ、実行時のパラメータを変更する。tpccの場合、デフォルト値は、nAgentsは16、measurementTimeは15分(900秒)、warmupTimeは300秒となるので、変えるならばこのあたりかと思う。 https://dbstudy.info/jdbcrunner/docs_ja/parameter.html cd /home/ec2-user/jdbcrunner-1.3/scripts java -server JR tpcc.js -warmupTime 5 -nAgents 10 -measurementTime 60 -warmupTime:ウォームアップ時間。バッファ上にキャッシュが溜まってから測定するようにする。 -nAgents:並列度 -measurementTime:測定時間 結果 22:13:07 [INFO ] [Progress] 898 sec, 263,277,28,27,27 tps, 237424,237414,23742,23744,23743 tx 22:13:08 [INFO ] [Progress] 899 sec, 274,264,25,28,26 tps, 237698,237678,23767,23772,23769 tx 22:13:09 [INFO ] [Progress] 900 sec, 260,277,27,22,30 tps, 237958,237955,23794,23794,23799 tx 22:13:09 [INFO ] [Total tx count] 237958,237955,23794,23794,23799 tx 22:13:09 [INFO ] [Throughput] 264.4,264.4,26.4,26.4,26.4 tps 22:13:09 [INFO ] [Response time (minimum)] 2,2,0,17,1 msec 22:13:09 [INFO ] [Response time (50%tile)] 38,7,3,81,9 msec 22:13:09 [INFO ] [Response time (90%tile)] 63,14,5,111,15 msec 22:13:09 [INFO ] [Response time (95%tile)] 70,23,6,132,17 msec 22:13:09 [INFO ] [Response time (99%tile)] 93,50,8,184,22 msec 22:13:09 [INFO ] [Response time (maximum)] 478,429,208,445,135 msec 22:13:09 [INFO ] < JdbcRunner SUCCESS 結果の見方 https://dbstudy.info/jdbcrunner/docs_ja/tpc-c.html TPC-Cでは5種類のトランザクションが定義されており、結果は左からNew-Order、Payment、Order-Status、Delivery、Stock-Levelトランザクションのものとなっています。 TPC-CのスコアにはNew-Orderトランザクションの1分あたりの実行回数を用いることが多いです。上記の例では15分間で42,727txですから、スコアは2,848.5tpmとなります。 実行時のPerformace Insigthsの画面。 --- ### Redshift Star Schema Benchmark 問い合わせクエリのサンプル date: 2021-06-28 url: https://zatoima.github.io/aws-redshift-spectrum-data-query-execute/ tags: AWS, Redshift 下記のスタースキーマのデータをRedshiftにぶっ込んでいるという前提。 s3://awssampledbuswest2/ssbgz/ Redshift Spectrumへのクエリのために、スキーマをs3としているので適宜置換が必要。 Star Schema Benchmark問合せ select sum(lo_extendedprice*lo_discount) as revenue from s3.lineorder, s3.dwdate where lo_orderdate = d_datekey and d_yearmonthnum = 199401 and lo_discount between 4 and 6 and lo_quantity between 26 and 35; select sum(lo_extendedprice*lo_discount) as revenue from s3.lineorder, s3.dwdate where lo_orderdate = d_datekey and d_year = 1993 and lo_discount between 1 and 3 and lo_quantity < 25; select sum(lo_extendedprice*lo_discount) as revenue from s3.lineorder, s3.dwdate where lo_orderdate = d_datekey and d_yearmonthnum = 199401 and lo_discount between 4 and 6 and lo_quantity between 26 and 35; select sum(lo_extendedprice*lo_discount) as revenue from s3.lineorder, s3.dwdate where lo_orderdate = d_datekey and d_weeknuminyear = 6 and d_year = 1994 and lo_discount between 5 and 7 and lo_quantity between 26 and 35; select sum(lo_revenue), d_year, p_brand1 from s3.lineorder, s3.dwdate, s3.part, s3.supplier where lo_orderdate = d_datekey and lo_partkey = p_partkey and lo_suppkey = s_suppkey and p_category = 'MFGR#12' and s_region = 'AMERICA' group by d_year, p_brand1 order by d_year, p_brand1; select sum(lo_revenue), d_year, p_brand1 from s3.lineorder, s3.dwdate, s3.part, s3.supplier where lo_orderdate = d_datekey and lo_partkey = p_partkey and lo_suppkey = s_suppkey and p_brand1 between 'MFGR#2221' and 'MFGR#2228' and s_region = 'ASIA' group by d_year, p_brand1 order by d_year, p_brand1; select sum(lo_revenue), d_year, p_brand1 from s3.lineorder, s3.dwdate, s3.part, s3.supplier where lo_orderdate = d_datekey and lo_partkey = p_partkey and lo_suppkey = s_suppkey and p_brand1 = 'MFGR#2221' and s_region = 'EUROPE' group by d_year, p_brand1 order by d_year, p_brand1; select c_nation, s_nation, d_year, sum(lo_revenue) as revenue from s3.customer, s3.lineorder, s3.supplier, s3.dwdate where lo_custkey = c_custkey and lo_suppkey = s_suppkey and lo_orderdate = d_datekey and c_region = 'ASIA' and s_region = 'ASIA' and d_year >= 1992 and d_year <= 1997 group by c_nation, s_nation, d_year order by d_year asc, revenue desc; select c_city, s_city, d_year, sum(lo_revenue) as revenue from s3.customer, s3.lineorder, s3.supplier, s3.dwdate where lo_custkey = c_custkey and lo_suppkey = s_suppkey and lo_orderdate = d_datekey and c_nation = 'UNITED STATES' and s_nation = 'UNITED STATES' and d_year >= 1992 and d_year <= 1997 group by c_city, s_city, d_year order by d_year asc, revenue desc; select c_city, s_city, d_year, sum(lo_revenue) as revenue from s3.customer, s3.lineorder, s3.supplier, s3.dwdate where lo_custkey = c_custkey and lo_suppkey = s_suppkey and lo_orderdate = d_datekey and (c_city='UNITED KI1' or c_city='UNITED KI5') and (s_city='UNITED KI1' or s_city='UNITED KI5') and d_year >= 1992 and d_year <= 1997 group by c_city, s_city, d_year order by d_year asc, revenue desc; select c_city, s_city, d_year, sum(lo_revenue) as revenue from s3.customer, s3.lineorder, s3.supplier, s3.dwdate where lo_custkey = c_custkey and lo_suppkey = s_suppkey and lo_orderdate = d_datekey and (c_city='UNITED KI1' or c_city='UNITED KI5') and (s_city='UNITED KI1' or s_city='UNITED KI5') and d_yearmonth = 'Dec1997' group by c_city, s_city, d_year order by d_year asc, revenue desc; select d_year, c_nation, sum(lo_revenue - lo_supplycost) as profit from s3.dwdate, s3.customer, s3.supplier, s3.part, s3.lineorder where lo_custkey = c_custkey and lo_suppkey = s_suppkey and lo_partkey = p_partkey and lo_orderdate = d_datekey and c_region = 'AMERICA' and s_region = 'AMERICA' and (p_mfgr = 'MFGR#1' or p_mfgr = 'MFGR#2') group by d_year, c_nation order by d_year, c_nation; select d_year, s_nation, p_category, sum(lo_revenue - lo_supplycost) as profit from s3.dwdate, s3.customer, s3.supplier, s3.part, s3.lineorder where lo_custkey = c_custkey and lo_suppkey = s_suppkey and lo_partkey = p_partkey and lo_orderdate = d_datekey and c_region = 'AMERICA' and s_region = 'AMERICA' and (d_year = 1997 or d_year = 1998) and (p_mfgr = 'MFGR#1' or p_mfgr = 'MFGR#2') group by d_year, s_nation, p_category order by d_year, s_nation, p_category; select d_year, s_city, p_brand1, sum(lo_revenue - lo_supplycost) as profit from s3.dwdate, s3.customer, s3.supplier, s3.part, s3.lineorder where lo_custkey = c_custkey and lo_suppkey = s_suppkey and lo_partkey = p_partkey and lo_orderdate = d_datekey and c_region = 'AMERICA' and s_nation = 'UNITED STATES' and (d_year = 1997 or d_year = 1998) and p_category = 'MFGR#14' group by d_year, s_city, p_brand1 order by d_year, s_city, p_brand1; --- ### Google カスタム検索エンジンでHugoのサイト内検索を行う date: 2021-06-27 url: https://zatoima.github.io/hugo-google-custom-search-engine/ tags: Hugo 前提条件 カスタムエンジン側の設定が完了済なこと config.tomlの編集 メニューバーに追加したいので、下記を追加する [[Menus.main]] Name = "search" URL = "/search/" content/search配下にindex.htmlを追加 --- title: "Search" --- <form action="https://cse.google.com/cse"> <div class="searchBox"> <input type="hidden" name="cx" value="1ef1df26a465b967e" /> <input type="hidden" name="ie" value="UTF-8" /> <input type="search" name="q" placeholder="Googleカスタム検索" size="30" autocomplete="off" /> <input type="submit" value="検索" /> </div> </form> 結果 メニューバー、及び検索ボックスが準備できた このようなURL形式になるのでコマンドラインランチャー等から検索できるのも良い https://cse.google.com/cse?cx=<検索エンジンID>=UTF-8&q=<検索文字列> --- ### HugoのテーマをAcademicからMainroadに変更した date: 2021-06-26 url: https://zatoima.github.io/hugo-academic-to-hugo-change/ tags: Hugo Academicの後継バージョンがよくわからなくなっていたので、Mainroadというテーマに変更した。 参考サイト HUGOのテーマ「Mainroad」の設定方法を紹介 https://itsys-tech.com/list/hugo/007/ Hugo によるブログ作成と mainroad テーマのカスタマイズ - terashim.com https://terashim.com/posts/create-hugo-blog-and-customize-mainroad-theme/ また、今まではPublic配下のみをGithubにpushしていたが、hugo配下を全てpushするようにした。GitHub Pagesの設定にもどこのディレクトリを公開するかを選べる。 今後やりたいこと 全文検索機能 メモとして使っているので、、。できればURLにキーワードを渡すことで検索結果が出るようにしたい Hugo + Lunrによる日本語全文検索 が良さそう ブログ名が全部大文字になっているのをどうにかしたい Socialリンクを貼る --- ### AWSの各サービスクォーター(Service Quotas)をCLIから確認 date: 2021-06-23 url: https://zatoima.github.io/aws-service-quotas-limit-cli/ tags: AWS サービス一覧とサービスコードを確認する aws service-quotas list-services --output table -------------------------------------------------------------------------------------------------------- | ListServices | +------------------------------------------------------------------------------------------------------+ || Services || |+--------------------------+-------------------------------------------------------------------------+| || ServiceCode | ServiceName || |+--------------------------+-------------------------------------------------------------------------+| || AWSCloudMap | AWS Cloud Map || || access-analyzer | Access Analyzer || || acm | AWS Certificate Manager (ACM) || || acm-pca | AWS Certificate Manager Private Certificate Authority (ACM PCA) || || airflow | Amazon Managed Workflows for Apache Airflow || || amplify | AWS Amplify || || apigateway | Amazon API Gateway || || appflow | Amazon AppFlow || || application-autoscaling | Application Auto Scaling || || appmesh | AWS App Mesh || || apprunner | AWS App Runner || || appstream2 | Amazon AppStream 2.0 || || appsync | AWS AppSync || || athena | Amazon Athena || || auditmanager | AWS Audit Manager || サービスクォーターを確認 list-service-quotasを使用する。指定されたAWSサービスに適用されたクォータ値を一覧表示する。 パラメータの補足↓ Adjustable:上限緩和が可能かどうか(ハードリミットかソフトリミットかが確認可能) aws service-quotas list-service-quotas --service-code athena --output table -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ListServiceQuotas | +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ || Quotas || |+------------+--------------+-----------------------------------------------------------------------+-------------+--------------------+--------------+----------------+-------+---------+| || Adjustable | GlobalQuota | QuotaArn | QuotaCode | QuotaName | ServiceCode | ServiceName | Unit | Value || |+------------+--------------+-----------------------------------------------------------------------+-------------+--------------------+--------------+----------------+-------+---------+| || True | False | arn:aws:servicequotas:ap-northeast-1:0123456789:athena/L-3CE0BBA0 | L-3CE0BBA0 | DDL query limit | athena | Amazon Athena | None | 20.0 || || True | False | arn:aws:servicequotas:ap-northeast-1:0123456789:athena/L-56A94400 | L-56A94400 | DDL query timeout | athena | Amazon Athena | None | 600.0 || || True | False | arn:aws:servicequotas:ap-northeast-1:0123456789:athena/L-FC5F6546 | L-FC5F6546 | DML query limit | athena | Amazon Athena | None | 30.0 || || True | False | arn:aws:servicequotas:ap-northeast-1:0123456789:athena/L-E80DC288 | L-E80DC288 | DML query timeout | athena | Amazon Athena | None | 30.0 || |+------------+--------------+-----------------------------------------------------------------------+-------------+--------------------+--------------+----------------+-------+---------+| サービスクォーターのデフォルト値を確認 list-aws-default-service-quotasはデフォルト値のみを出力する。上限緩和等で値が変更された場合の結果は反映されないので注意。QuotaArnにもアカウント番号が出てこないところを見ると各アカウントで同じ結果になるものと思われる。 aws service-quotas list-aws-default-service-quotas --service-code athena --output table -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ListAWSDefaultServiceQuotas | +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ || Quotas || |+------------+--------------+-----------------------------------------------------------+-------------+--------------------+--------------+----------------+-------+---------+| || Adjustable | GlobalQuota | QuotaArn | QuotaCode | QuotaName | ServiceCode | ServiceName | Unit | Value || |+------------+--------------+-----------------------------------------------------------+-------------+--------------------+--------------+----------------+-------+---------+| || True | False | arn:aws:servicequotas:ap-northeast-1::athena/L-3CE0BBA0 | L-3CE0BBA0 | DDL query limit | athena | Amazon Athena | None | 20.0 || || True | False | arn:aws:servicequotas:ap-northeast-1::athena/L-56A94400 | L-56A94400 | DDL query timeout | athena | Amazon Athena | None | 600.0 || || True | False | arn:aws:servicequotas:ap-northeast-1::athena/L-FC5F6546 | L-FC5F6546 | DML query limit | athena | Amazon Athena | None | 30.0 || || True | False | arn:aws:servicequotas:ap-northeast-1::athena/L-E80DC288 | L-E80DC288 | DML query timeout | athena | Amazon Athena | None | 30.0 || |+------------+--------------+-----------------------------------------------------------+-------------+--------------------+--------------+----------------+-------+---------+| CSV形式で抽出したい時 aws service-quotas list-services | jq -r '.Services[] | [.ServiceCode, .ServiceName] | @csv' aws service-quotas list-service-quotas --service-code athena | jq -r '.Quotas[] | [.ServiceCode, .ServiceName, .QuotaName, .Value, .Unit, .Adjustable] | @csv' aws service-quotas list-aws-default-service-quotas --service-code athena | jq -r '.Quotas[] | [.ServiceCode, .ServiceName, .QuotaName, .Value, .Unit, .Adjustable] | @csv' 参考 AWS のサービスクォータ - AWS 全般のリファレンス https://docs.aws.amazon.com/ja_jp/general/latest/gr/aws_service_limits.html list-service-quotas — AWS CLI1.19.97コマンドリファレンス https://docs.aws.amazon.com/cli/latest/reference/service-quotas/list-service-quotas.html list-aws-default-service-quotas — AWS CLI 1.19.97 Command Reference https://docs.aws.amazon.com/cli/latest/reference/service-quotas/list-aws-default-service-quotas.html AWS CLI を使用してサービスクォータの引き上げをリクエストする https://aws.amazon.com/jp/premiumsupport/knowledge-center/request-service-quota-increase-cli/ --- ### Redshift Admin Scripts date: 2021-06-20 url: https://zatoima.github.io/aws-redshift-admin-script-memo/ tags: AWS, Redshift 一覧 No. スクリプト 概要 1 commit_stats.sql COMMIT文によるクラスタリソースの消費に関する情報を表示 2 copy_performance.sql 過去7日間で最も長く実行されたコピーを表示 3 current_session_info.sql 現在実行中のクエリを持つセッションについての情報を表示するクエリ 4 filter_used.sql スキャン時にテーブルに適用されるフィルタを返す。ソートキーの選択に役立ちます。 5 generate_calendar.sql スタースキーマ結合に便利なカレンダー・ディメンジョン・テーブルの作成 6 missing_table_stats.sql クエリには、基礎となるテーブルで「統計情報がない」というフラグを立てた EXPLAIN プランが表示 7 perf_alert.sql アラート、テーブルスキャンとの結合、SQLテキストの上位出現率を返す 8 table_alerts.sql テーブルアクセスに関連するアラートの発生件数を返す 9 predicate_columns.sql テーブル上のプレディケート・カラムに関する情報を返す 10 queuing_queries.sql WLM クエリスロットで待機しているクエリの表示 11 queue_resources_hourly.sql WLM クエリキューの時間ごとのリソース使用量を返す 12 running_queues.sql 実行中およびキューイング中のクエリと消費されたリソースを返す 13 table_info.sql テーブルのストレージ情報(サイズ、スキューなど)を返す 14 table_inspector.sql テーブル設計の分析」の内容に基づくテーブルの分析。table_info.sqlを補完 15 top_queries.sql 過去7日間で最も時間を消費したステートメントのトップ50を返す 16 top_queries_and_cursors.sql 過去7日間で最も時間を消費したステートメントのトップ50を返す - カーソルテキストを含む 17 unscanned_table_summary.sql スキャンされていないテーブルで消費されたストレージをまとめます。 18 wlm_apex.sql WLM クエリキューの全体的なハイウォーターマークとキューが最後に発生した時間を返す 19 wlm_apex_hourly.sql WLM クエリキューの時間ごとのハイウォーターマークを返す 20 wlm_qmr_rule_candidates.sql 新しい WLM クエリ監視ルールの候補を算出 21 user_to_be_dropped_objs.sql ドロップできないユーザが所有するオブジェクトの検索 22 user_to_be_dropped_privs.sql ドロップできないユーザに付与されている権限の検索 https://github.com/awslabs/amazon-redshift-utils/tree/master/src/AdminScripts 実行 \i commit_stats.sql; \i copy_performance.sql; \i current_session_info.sql; \i filter_used.sql; \i generate_calendar.sql; \i insert_into_table_dk_mismatch.sql; \i lock_wait.sql; \i missing_table_stats.sql; \i perf_alert.sql; \i predicate_columns.sql; \i queue_resources_hourly.sql; \i queuing_queries.sql; \i running_queues.sql; \i table_alerts.sql; \i table_info.sql; \i table_inspector.sql; \i top_queries_and_cursors.sql; \i top_queries.sql; \i unscanned_table_summary.sql; \i user_to_be_dropped_objs.sql; \i user_to_be_dropped_privs.sql; \i wlm_apex_hourly.sql; \i wlm_apex.sql; \i wlm_qmr_rule_candidates.sql; --- ### EMR PySparkでWordCount date: 2021-06-19 url: https://zatoima.github.io/aws-emr-spark-python-wordcount/ tags: AWS, EMR WordCountするデータの準備 head -c 200m /dev/urandom > test.txt hadoop fs -put test.txt /user/hadoop/ hadoop fs -ls /user/hadoop/ 実行用PySparkのスクリプト from pyspark.sql.types import * from pyspark import SparkConf, SparkContext from pyspark.sql.session import SparkSession from operator import add sc = SparkContext.getOrCreate() spark = SparkSession(sc) inputFile = "/user/hadoop/test.txt" lines = sc.textFile(inputFile) lines_nonempty = lines.filter( lambda x: len(x) > 0 ) counts = lines_nonempty.flatMap(lambda x: x.split(' ')).map(lambda x: (x, 1)).reduceByKey(add) output = counts.collect() for (word, count) in output: print("%s: %i" % (word, count)) sc.stop() 実行 spark-submit test.py --- ### pgbenchで任意のSQLを使って負荷掛け date: 2021-06-16 url: https://zatoima.github.io/postgresql-pgbench-performance-sql-test/ tags: PostgreSQL 実行するSQL cat << EOF > query.sql <SQL文をここに書く> EOF pgbenchを使った並列実行 この場合はクライアント数が5、スレッド数5で100回SQLを実行するパターン。 pgbench -r -c 5 -j 5 -n -t 100 -f query.sql -U awsuser -h aurora-postgresql.xxxxxx.ap-northeast-1.redshift.amazonaws.com -d postgres -p 5439 各オプションの説明 pgbench https://www.postgresql.jp/document/12/html/pgbench.html -j threads --jobs=threads pgbench内のワーカスレッド数 -r --report-latencies ベンチマーク完了後の各コマンドにおけるステートメント毎の平均レイテンシ(クライアントから見た実行時間)を報告 -c clients --client=clients 模擬するクライアント数、つまり、同時に実行されるデータベースセッション数 -f filename --file=filename 実行するSQLを指定する -t transactions --transactions=transactions 各クライアントが実行するトランザクション数。 デフォルトは10。 --- ### Redshift ショートクエリアクセラレーション(SQA) date: 2021-06-15 url: https://zatoima.github.io/aws-redshift-short-query-acceleration-sqa/ tags: AWS, Redshift ショートクエリアクセラレーション(SQA)とは 実行時間が短い一部のクエリを、実行時間が長いクエリよりも優先するように専用キューで実行する機能 ロングクエリ実行中に、ショートクエリがブロックされるシチューエーションを回避出来る デフォルトでは、WLM は、クラスターのワークロードの分析に基づいて、SQA 最大実行時間の値を動的に割り当て 特にユーザは意識する必要はない 実機確認 下記クエリで動的に割り当てられたショートクエリの実行時間がわかる select least(greatest(percentile_cont(0.7) within group (order by total_exec_time / 1000000) + 2, 2), 20) from stl_wlm_query where userid >= 100 and final_state = 'Completed'; mydb=# tpcds_100gb=# select least(greatest(percentile_cont(0.7) mydb(# tpcds_100gb(# within group (order by total_exec_time / 1000000) + 2, 2), 20) mydb(# tpcds_100gb-# from stl_wlm_query mydb(# tpcds_100gb-# where userid >= 100 mydb(# tpcds_100gb-# and final_state = 'Completed'; mydb(# least mydb(# ------- mydb(# 8.0 mydb(# (1 row) 有効化確認 select * from stv_wlm_service_class_config where service_class = 14; mydb=# select * from stv_wlm_service_class_config mydb-# where service_class = 14; -[ RECORD 1 ]------------+----------------------------------------------------------------- service_class | 14 queueing_strategy | Predicted Time queue policy num_query_tasks | 6 target_num_query_tasks | 6 evictable | true eviction_threshold | 0 query_working_mem | 264 target_query_working_mem | 264 min_step_mem | 5 name | Short query queue max_execution_time | 0 user_group_wild_card | false query_group_wild_card | false concurrency_scaling | off query_priority | Normal 各クエリキュー (サービスクラス) を通過したクエリ確認 select final_state, service_class, count(*), avg(total_exec_time), percentile_cont(0.9) within group (order by total_queue_time), avg(total_queue_time) from stl_wlm_query where userid >= 100 group by 1,2 order by 2,1; mydb=# select final_state, service_class, count(*), avg(total_exec_time), mydb-# percentile_cont(0.9) within group (order by total_queue_time), avg(total_queue_time) mydb-# from stl_wlm_query where userid >= 100 group by 1,2 order by 2,1; final_state | service_class | count | avg | percentile_cont | avg ------------------+---------------+-------+---------+-----------------+-------- Completed | 100 | 283 | 1789760 | 550958.6 | 421287 (1 row) SOAによって正常完了したクエリの情報 select a.queue_start_time, a.total_exec_time,trim(querytxt) from stl_wlm_query a, stl_query b where a.query = b.query and a.service_class = 14 and a.final_state = 'Completed' order by a.queue_start_time desc limit 1; mydb=# select a.queue_start_time, a.total_exec_time,trim(querytxt) mydb-# from stl_wlm_query a, stl_query b mydb-# where a.query = b.query and a.service_class = 14 and a.final_state = 'Completed' mydb-# order by a.queue_start_time desc limit 1; queue_start_time | total_exec_time | btrim 2021-06-11 12:38:23.935373 | 1983019 | with /* TPC-DS query27a.tpl 0.16 */ results as (select i_item_id, s_state, 0 as g_state, ss_quantity agg1, ss_list_price agg2, ss_coupon_amt agg3, ss_sales_price agg4 from store_sales, customer_demographics, date_dim, store, item where ss_sold_date_sk = d_date_sk and ss_item_sk = i_item_sk and ss_store_sk = s_store_sk and ss_cdemo_sk = cd_demo_sk and cd_gender = 'F' and cd_marital_status = 'S' and cd_education_status = 'Primary' and d_year = 1999 and s_state in ('FL','NC', 'MN', 'CO', 'MI', 'SC') ) select i_item_id, s_state, g_state, agg1, agg2, agg3, agg4 from ( select i_item_id, s_state, 0 as g_state, avg(agg1) agg1, avg(agg2) agg2, avg(agg3) agg3, avg(agg4) agg4 from results group by i_item_id, s_state union all select i_item_id, NULL AS s_state, 1 AS g_state, avg(agg1) agg1, avg(agg2) agg2, avg(agg3) agg3, avg(agg4) agg4 from results group by i_item_id union all select NULL AS i_item_id, NULL as s_state, 1 as g_state, avg(agg1) agg1, avg(agg2) agg2, avg(agg3) agg3, avg(agg4) agg4 from results ) fo o order by i_item_id, s_state limit 100; (1 row) --- ### Redshiftクラスタ 停止、起動、状態確認のCLI操作 date: 2021-06-12 url: https://zatoima.github.io/aws-redshift-cluster-stop-start-check-status/ tags: AWS, Redshift 停止 aws redshift pause-cluster --cluster-identifier redshift-ra3 起動(再開) aws redshift resume-cluster --cluster-identifier redshift-ra3 状態確認 aws redshift describe-clusters --cluster-identifier redshift-ra3 describe-clustersで必要な情報だけ取得する [ec2-user@bastin ~]$ aws redshift describe-clusters --cluster-identifier redshift-ra3 | jq -r '.Clusters[] | [ .ClusterIdentifier, .NodeType, .ClusterStatus] | @csv' "redshift-ra3","ra3.4xlarge","paused" --- ### AWSにおける暗号化されたバックアップのリージョン間コピー date: 2021-06-11 url: https://zatoima.github.io/aws-backup-encrypt-tokyo-to-osaka/ tags: AWS KMSはリージョン内に閉じたサービスであるため、暗号化されたスナップショットを転送する場合は、一度転送元のリージョンで復号され、転送先の別のCMKで暗号化されることとなる。 多くのサービスでリージョン間コピーする際に宛先リージョンのKMSのCMKを指定することとなる。 リージョン間の転送もセキュアとなる。(利用者は意識しないところ) イメージ図 マニュアル AWS Backup https://docs.aws.amazon.com/ja_jp/aws-backup/latest/devguide/cross-region-backup.html AWS Backup は、コピー先のボールトの顧客管理キーを使用してコピーを再暗号化します。 Redshift の場合 https://docs.aws.amazon.com/ja_jp/redshift/latest/mgmt/working-with-db-encryption.html#working-with-aws-kms スナップショットがターゲットの AWS リージョンにコピーされる前に、Amazon Redshift はソースの AWS リージョンでマスターキーを使用してスナップショットを復号し、Amazon Redshift が内部で管理しているランダムに生成された RSA キーを使用して一時的に再暗号化します。その後、Amazon Redshift は安全なチャンネル経由でターゲットの AWS リージョンにコピーし、が内部で管理している RSA キーを使用してスナップショットを復号してから、ターゲットの AWS リージョンでマスターキーを使用してスナップショットを再暗号化します。 Auroraの場合 https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/USER_CopySnapshot.html AWS KMS カスタマーマスターキー (CMK) を使用して暗号化されたスナップショットをコピーできます。暗号化された スナップショットをコピーする場合は、スナップショットのコピーも暗号化する必要があります。同じ AWS リージョン内で暗号化されているスナップショットをコピーする場合、元のスナップショットと同じ AWS KMS CMK を使用してコピーを暗号化できます。または、別の CMK を指定することもできます。リージョン間で暗号化されているスナップショットをコピーする場合、ソーススナップショットに使用されているのと同じ AWS KMS CMK をコピーに使用することはできません。なぜなら、AWS KMS CMK はリージョン固有だからです。代わりに、ターゲット AWS リージョンで有効な AWS KMS CMK を指定する必要があります。 RDSの場合 https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Overview.Encryption.html ある AWS リージョンから別のリージョンに暗号化されたスナップショットをコピーするには、コピー先の AWS リージョンの CMK を指定する必要があります。これは、CMK が、作成される AWS リージョンに固有であるためです。 ソーススナップショットは、コピープロセス中も暗号化されたままになります。Amazon RDS は、コピープロセス処理中にエンベロープ暗号化を使用してデータを保護します。エンベロープ暗号化の仕組みの詳細については、AWS Key Management Service デベロッパーガイドの「エンベロープ暗号化」を参照してください。 注意点 別の AWS リージョンへの自動バックアップのレプリケーションという機能がRDSにあるが、この機能は暗号化されているDBインスタンスではサポートされていないので注意。 https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_ReplicateBackups.html バックアップレプリケーションは、次のデータベースエンジンを実行する RDS DB インスタンスで使用できます。 Oracle バージョン 12.1.0.2.v10 以降 PostgreSQL バージョン 9.6 以降 バックアップレプリケーションは、暗号化された DB インスタンスではサポートされていません。 --- ### awslabsのpg-collectorについて date: 2021-06-10 url: https://zatoima.github.io/aws-aurora-rds-postgresql-pg-collector.html tags: AWS, PostgreSQL, Aurora, RDS AWS環境のPostgreSQLベースのRDS、Auroraから主に静的情報を抽出する時に手軽に実施出来るのでメモ。 GitHub - awslabs/pg-collector https://github.com/awslabs/pg-collector pg_stat_statementsを有効化 ※pg_stat_statements自体は必須ではない。インストールしないとレポート内にエラーが記録される CREATE EXTENSION pg_stat_statements; 既にpg_stat_statementsが導入済で稼働統計が溜まっている際に性能試験を実施する場合には、事前にpg_stat_statementsの統計値をリセットした上で実施した方が良い。 postgres=# SELECT pg_stat_statements_reset(); pg_stat_statements_reset -------------------------- スクリプトを実行 git clone https://github.com/awslabs/pg-collector.git cd pg-collector psql -h aurorapgsqlv1.cluster-xxxxx.ap-northeast-1.rds.amazonaws.com -U postgres -d postgres \i pg_collector.sql 実行イメージ postgres=> \i pg_collector.sql Output format is aligned. Report name and location: /tmp/pg_collector_postgres-2021-06-10_154014.html postgres=> 出力レポートイメージ http://pg-collector.s3-website-us-west-2.amazonaws.com/pg_collector_postgres-2020-12-14_053537.html この辺のテーブル情報を取得する。様々なpg_catalogから抽出してくれるのでぱっと情報を取得して眺めたい時にはいいかもしれない Database size Configuration parameters Installed extensions Vacuum & Statistics Unused Indexes & invalid indexes Users & Roles Info Toast Tables Mapping Database schemas Fragmentation (Bloat) Tablespaces Info Memory setting Tables and Indexes Size and info Transaction ID Replication slots public Schema info Unlogged Tables --- ### Aurora PostgreSQLのIO料金について date: 2021-06-04 url: https://zatoima.github.io/aws-aurora-cost-io-input-output.html tags: AWS, Aurora Auroraのコストは大きく下記の4つに分類される。RDS PostgreSQL等の他のRDBMS系のデータベースサービスはIO料金が掛からず、それもあってかAuroraのIO料金は見積もりにも見落としがちとなる。(IO料金についてはインスタンス料金の数%から高くても10%に収まる感触を持っているが、データベースの使い方によっては高い料金になる可能性もある。) インスタンス料金 データベースストレージ IO料金 データ転送量 詳細は下記をご参照。クローニングやグローバルデータベースの利用料については使い方によるので省略。 料金 - Amazon Aurora | AWS https://aws.amazon.com/jp/rds/aurora/pricing/ 東京リージョンのIO料金については0.24USD/100 万リクエストとなる。また、各データページで最大 4KB の変更に対して 1 回の I/O オペレーションを課金される。仮に秒間2000IOPS発生するワークロードあった場合の月額費用は下記で計算される。(なお、秒間2,000IOPSというワークロードはあくまでも目安として。) 1,000 Reads/Second + 1,000 Writes/Second = 2,000 Number of I/Os per second 2,000 I/Os per second x 730 hours x 60 minutes x 60 Seconds = 5,256,000,000 Number of I/Os per month 5,256,000,000 x 0.00000024 USD = 1,261.44 USD (I/O Rate Cost) なお、料金自体はPricing Calculatorで計算出来る。 AWS Pricing Calculator https://calculator.aws/#/createCalculator/AuroraPostgreSQL AuroraのIO料金が高いときには下記を確認する。 CloudWatchでBilled IOPSを確認する スパイクしている際にどんなオペレーションをやっているか確認してIO量を減らせないか確認する pg_dump、バッチ処理、フルスキャン等 Performance Insights で IO: DataFileRead や IO:DataFilePrefetch あたりが発生しているSQLを確認する バッファキャッシュヒット率を確認する データファイルI/Oが発生しているのでオンメモリになるようにパラメータを調整 IO料金を下げるためのアクションとしては下記が中心となる メモリを大きくしてオンメモリで処理出来るようにする フルスキャン系のSQLをチューニングする インデックスやパーティションを使って不要なIOを削減する 追記(2022/02/02) 次の記事も参考になる、というか2022年1月に公式から出たAWS Database Blogをしっかり読んだ方が良い。 ・Planning I/O in Amazon Aurora | AWS Database Blog --- ### Redshift RA3 と Spectrumの使い分け date: 2021-05-31 url: https://zatoima.github.io/aws-redshift-ra3-spectrum.html tags: AWS, Redshift どちらもコンピュートとストレージ層が分離されているアーキテクチャのため、どういうユースケースのときにどっちを使うべきかという疑問。 例 RA3パターン S3にデータをオフロードしてストレージを節約しているパターン等はRA3に Redshift内でETLを行いデータを加工するパターン S3上でのパーティション分割などSpectrumからのスキャン性能とかあまり気にしたくない時に Spectrum 他のAWSサービスからS3上のデータにアクセスするパターン。現時点においてもDWH上にデータを置いていないパターン等はSpectrumへ。(この場合はAthenaとの使い分けがまた悩みどころ…。) EMRでデータを加工してRedshiftでデータを参照するパターン Redshift内のデータと組み合わせて使うパターン --- ### Apache Sparkの構成要素、概要、用語について date: 2021-05-27 url: https://zatoima.github.io/aws-emr-spark-concept-component.html tags: AWS, EMR, Spark HadoopとSparkの違い 分散ファイルシステム層のHDFSやリソース管理のYARN等の層はHadoopもSparkも同じ。(StandAloneやmesos等もある。) Map Reduce部分がSparkになる。 Hadoop Spark Sparkコンポーネント Driver、及び実際にジョブを実行するWorker Nodeが存在。Worker Nodeの中にExecutorが存在して、複数のタスクを実行可能 https://spark.apache.org/docs/3.1.1/cluster-overview.html Driverの役割 Spark Shellのエントリーポイント SparkContextが作られる場所 RDDを実行グラフに翻訳する 実行グラフをステージに分割する 実行のタスクをスケジュールして制御する RDDとパーティションのメタデータを保存 Spark WebUIを提供 Executorの役割 JVM HeapまたはDiskのキャッシュにデータを保存 外部データソースからデータを読み込む データを書き出す すべてのデータ処理を実行する RDD(Resilient Distributed Data) Recordの集合体がPartition、Partitionの集まりがRDDとなる。 Partition単位で各Executorノードに配布される Partitionの数は設定可能。少ない場合はExecutorに割り当てられるタスクが減るので同時実行性の低下、データの偏り、分散処理の利点が活かせない。 デフォルトではPartition数=コア数 SparkはPartitionごとに1つのタスクを割り当て、各Workerは一度に1つのタスクを処理する DataFrame RDDと同じように各ノードに分散配置されたデータのコレクション DataFrameはRDBMSにおけるテーブルに似ており、このようにデータを構造化することによってSpark SQLを使ってクエリを実行 Pythonの場合、RDDでのデータ処理は一般的に遅いと言われていたが、DataFrameベースで処理を行うことで他言語と性能的なデメリットはない Data Set Python(Pyspark)やRでは使えない。割愛。 DAG(Directed Acyclic Graph:有向非巡回グラフ) グラフ理論における閉路のない有向グラフのことである。有向グラフは頂点と有向辺(方向を示す矢印付きの辺)からなり、辺は頂点同士をつなぐが、ある頂点vから出発し、辺をたどり、頂点vに戻ってこないのが有向非巡回グラフである DAG schedulerがDAGをstageに変換してステージの各パーティションを1つずつのtaskに変換する。この時、RDDの変換(Transform)とアクション(Action)を分けることによって、データの不要なシャッフルをできるだけ回避するようにしたりしてクエリを最適化する。 このDAGは遅延評価と呼ばれており、実際のアクションが走った段階で、RDDやDataFrameが各パーティション単位で配分されて計算処理が実施される 分散処理をするには、データだけでなくロジックも渡す必要がある。最初にデータパイプライン全体をDAGとして組み立ててから実行に移すことで、内部のスケジューラが分散システムにとって効率の良い実行計画を建てる SparkにおけるDAGの例 Job、Stage、Taskの関係 Job - Stage - Taskという処理単位 ジョブの分割単位(関数イメージ) Stageの単位で各Executorに配布される 合わせてRDDのPartition単位で各ノードで処理される Shuffle データの再分散を行うことであり、reduceByKeyやgroupByKeyのような特定の処理の場合に発生する Shuffleはネットワーク越しのデータ転送が行なわれるので、特に巨大なデータに対してShuffleをする場合は大量のディスクIOやネットワークIOが発生することになり、パフォーマンスに影響を与える。 [翻訳] Spark Architecture: Shuffle - Qiita https://qiita.com/giwa/items/08ac5bda1eabb8c597b3 https://qiita.com/kimutansk/items/3ae363bce568677f79b6 参考資料 Sparkの内部処理を理解する - Qiita https://qiita.com/uryyyyyyy/items/ba2dceb709f8701715f7 Spark on EMRの基礎をおさらいする - Qiita https://qiita.com/uryyyyyyy/items/34f3d228f339b32e6fb0 Apache Sparkの概要 - Qiita https://qiita.com/whata/items/8915182cbd3759eebe6d Spark の RDD、DataFrame、DAG と Glue の DynamicFrame などについて - ablog https://yohei-a.hatenablog.jp/entry/20180916/1537085186 --- ### Amazon EMRのWebツール(Gangliaなど)をSSHトンネルを使ってブラウザ表示 date: 2021-05-24 url: https://zatoima.github.io/aws-emr-web-ui-tool-ssh-tunnel-browser.html tags: AWS, EMR Spark Web UI等はマネージメントコンソールでポチっとやれば見れるようになっているが、その他のWeb系のGUIツールはSSHトンネルを駆使して見る必要がある。ステップとしては下記2つをやる必要がある。 SSHクライアント側でフォワーディングの設定を行う ブラウザ側でプロキシの設定を行う 1度やってみると簡単だが、後でやるときに忘れそうなのでメモ。 SSHクライアント側でフォワーディングの設定を行う 参考マニュアル オプション2: パート 1: ダイナミックポートフォワーディングを使用してマスターノードへの SSH トンネルをセットアップする - Amazon EMR https://docs.aws.amazon.com/ja_jp/emr/latest/ManagementGuide/emr-ssh-tunnel.html Xshell6の場合 トンネリングの設定のフォワーディングルールでDynamicを選択してリッスンポートを8157にする。(使っていないポートなら何でも良いが、後続のプロキシ設定と合わせる必要あり。) Puttyの場合 Connection-SSH-Tunnelsでダイナミックポートフォワードを設定する Sessionはマスターノードの接続を通常通り行う ブラウザ側のプロキシ設定 参考マニュアル オプション2: パート 2: マスターノードでホストされる Web サイトを表示するようにプロキシを設定する - Amazon EMR https://docs.aws.amazon.com/ja_jp/emr/latest/ManagementGuide/emr-connect-master-node-proxy.html Proxy Switchy Omegaをインストール https://chrome.google.com/webstore/detail/proxy-switchyomega/padekgcemlokbadohgkifijomclgjgif Proxy Switchy Omegaのオプションを開いてNew Profileを選択 Profile NameとPAC Profileを選択 PAC Scriptの入力項目に下記を貼り付けた後にApply Changesを選択 function FindProxyForURL(url, host) { if (shExpMatch(url, "*ec2*.amazonaws.com*")) return 'SOCKS5 localhost:8157'; if (shExpMatch(url, "*ec2*.compute*")) return 'SOCKS5 localhost:8157'; if (shExpMatch(url, "http://10.*")) return 'SOCKS5 localhost:8157'; if (shExpMatch(url, "*10*.compute*")) return 'SOCKS5 localhost:8157'; if (shExpMatch(url, "*10*.amazonaws.com*")) return 'SOCKS5 localhost:8157'; if (shExpMatch(url, "*.compute.internal*")) return 'SOCKS5 localhost:8157'; if (shExpMatch(url, "*ec2.internal*")) return 'SOCKS5 localhost:8157'; return 'DIRECT'; } ここまで終わったら下記のURLにアクセスすることで各Web UIにアクセスが出来るようになる。 --- ### PySparkでUDFを使用する場合の性能面の注意点 date: 2021-05-23 url: https://zatoima.github.io/aws-emr-spark-python-udf-performance/ tags: AWS, EMR PythonとJVM間で通信のラウンドトリップが発生ということに注意。 参照:O’Reilly Japan - 初めてのSpark https://www.oreilly.co.jp/books/9784873117348/ 3.3 DataFrameによるPySparkの高速化 DataFrameとCatalyst Optimizer(そしてProject Tungsten)が際立っているのは、最適化されていないRDDのクエリに比べてPySparkのクエリのパフォーマンスを向上させてくれることです。次の図にあるとおり、DataFrameが登場するまでRDDに対するPythonのクエリの速度はScalaの同じクエリに比べて半分以下になることもめずらしくありません。通常このクエリのパフォーマンスの低下は、PythonとJVM間でのコミュニケーションのオーバーヘッドによるものです。 DataFrameの登場は、Pythonでのパフォーマンスを大きく改善させたのみならず、Python、Scala、SQL、Rのパフォーマンスを同等にしたのです。DataFrameでPySparkが大幅に高速になるとはいっても、例外があることは忘れないようにしてください。最もよくあるのはPythonのUDFを使う場合で、こうするとPythonとJVMとの間で通信のラウンドトリップが生じます。これはRDDで演算処理を行うのと同じような最悪のケースになりうるので、注意が必要です。 Catalyst OptimizerのコードベースはScalaで書かれていますが、PythonもSparkのパフォーマンス最適化の恩恵が受けられます。基本的には、PySparkでのDataFrameでクエリを大きく高速化してくれているコードは、Pythonで書かれた2,000行程度のラッパーに過ぎません。 --- ### EMRのエラーをS3のログから確認 date: 2021-05-20 url: https://zatoima.github.io/aws-emr-error-log-s3-command.html tags: AWS, EMR ログダウンロード用のディレクトリを作成、及び移動 mkdir j-3PS6MU0W27GMG cd j-3PS6MU0W27GMG ログのダウンロード ※j-3PS6MU0W27GMGはCluster ID aws s3 sync s3://aws-logs-xxx-ap-northeast-1/elasticmapreduce/j-3PS6MU0W27GMG . 解凍 find . -type f -exec gunzip {} \; エラーとワーニングを検索 時系列に並ぶようにsort find . | grep log | xargs egrep "WARN|ERROR" | sort -k2 --- ### Redshiftのdecimalの数値計算時の注意点 date: 2021-05-13 url: https://zatoima.github.io/aws-redshift-decimal-calculate.html tags: AWS, Redshift はじめに 浮動小数点演算で細かいところまで保持したい場合はDECIMALを使うことになると思うが、DECIMALを数値計算に使用した場合、計算結果の有効桁数は格納先のDECIMALと異なるという。 https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_numeric_computations201.html DECIMAL の計算結果の精度とスケール 精度とスケール まずは精度とスケールの基本的理解から。 精度(Precision):全体の桁数 スケール(Scale):小数点以下の桁数 入力データ NUMBER型の定義 格納されるデータ 7,456,123.89 NUMBER 7456123.89 7,456,123.89 NUMBER(*,1) 7456123.9 7,456,123.89 NUMBER(9) 7456124 7,456,123.89 NUMBER(9,2) 7456123.89 7,456,123.89 NUMBER(9,1) 7456123.9 7,456,123.89 NUMBER(6) (精度を超えているため、受け入れられない) 7,456,123.89 NUMBER(7,-2) 7456100 Redshiftでの浮動小数点演算の仕様 例えば次のように一連のコマンドを実行する。これはaというカラムがdecimal(8,2)、bというカラムがdecimal(8,7)であり、このaとbに格納されている値を除算して、cのdecimal(38,23)に格納するパターンとなる。cに格納される値は小数点23位までしっかりと格納されて欲しいが、計算が入る場合の精度とスケールは小数点23位まで保持されない。このパターンの結果は0.33330000000000000000000となり、小数点4位まで保持されて、以降はゼロ詰めされている。 drop table test; create table test(a decimal(8,2), b decimal(8,7),c decimal(38,23)); insert into test values(1,3,null); select * from test; insert into test(c) select a/b from test; select * from test; 実行ログは次の通り。 mydb=# drop table test; DROP TABLE mydb=# create table test(a decimal(8,2), b decimal(8,7),c decimal(38,23)); CREATE TABLE mydb=# insert into test values(1,3,null); INSERT 0 1 mydb=# mydb=# select * from test; a | b | c ------+-----------+--- 1.00 | 3.0000000 | (1 row) mydb=# insert into test(c) select a/b from test; INSERT 0 1 mydb=# select * from test; a | b | c ------+-----------+--------------------------- 1.00 | 3.0000000 | | | 0.33330000000000000000000 (2 rows) このような結果になるのは次の計算式が適用されるため。(マニュアルからの抜粋) 今回は除算なので、スケールはmax(4,s1+p2-s2+1)、精度はp1-s1+s2+scaleで計算する必要がある。 オペレーション 分類 計算式 + または - スケール max(s1,s2) + または - 精度 max(p1-s1,p2-s2)+1+scale * スケール s1+s2 * 精度 p1+p2+1 / スケール max(4,s1+p2-s2+1) / 精度 p1-s1+s2+scale 表形式にするとこんな感じ。計算結果と格納先のcで格納出来るスケール、精度で差異が出た。このような仕様を理解した上でデータ型を決める必要がある。 カラム 変数 スケール、精度 a p1 8 a s1 2 b p2 8 b s2 7 計算結果 精度(全体の桁数) 17 計算結果 スケール(小数点以下の桁数) 4 c(格納先) 精度(全体の桁数) 38 c(格納先) スケール(小数点以下の桁数) 23 補足 各データベースで計算式が違う?下記はSQL Server。 https://docs.microsoft.com/ja-jp/sql/t-sql/data-types/precision-scale-and-length-transact-sql?view=sql-server-ver15 参照 https://tech.tvisioninsights.co.jp/entry/2018/08/22/100000 https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_numeric_computations201.html https://odashinsuke.hatenablog.com/entry/20100720/1279628893 https://docs.microsoft.com/ja-jp/sql/t-sql/data-types/precision-scale-and-length-transact-sql?redirectedfrom=MSDN&view=sql-server-ver15 --- ### Redshiftのskew tableを確認する date: 2021-05-12 url: https://zatoima.github.io/aws-redshift-skew-table-check/ tags: AWS, Redshift amazon-redshift-utilsを使用する git clone https://github.com/awslabs/amazon-redshift-utils.git SQL実行 [ec2-user@bastin ~]$ psql -h redshift-cluster.xxxxx.ap-northeast-1.redshift.amazonaws.com -U awsuser -d tickit -p 5439 -f /home/ec2-user/amazon-redshift-utils-master/src/AdminScripts/table_inspector.sql schemaname | tablename | tableid | size_in_mb | has_dist_key | has_sort_key | has_col_encoding | ratio_skew_across_slices | pct_slices_populated ------------+-----------+---------+------------+--------------+--------------+------------------+--------------------------+---------------------- public | category | 203866 | 56 | 1 | 1 | 1 | 0 | 100 public | date | 203868 | 88 | 1 | 1 | 1 | 0 | 100 public | event | 203871 | 72 | 1 | 1 | 1 | 0 | 100 public | listing | 203873 | 88 | 1 | 1 | 1 | 0 | 100 public | sales | 203875 | 104 | 1 | 1 | 1 | 0 | 100 public | users | 203862 | 168 | 1 | 1 | 1 | 0 | 100 public | venue | 203864 | 64 | 1 | 1 | 1 | 0 | 100 (7 rows) 列の説明 レポート項目 意味 has_dist_key テーブルに分散キーが存在するかどうかを示します。 1 はキーが存在することを示し、 0 はキーが存在しないことを示します。 has_sort_key テーブルにソートキーが存在するかどうかを示します。 1 はキーが存在することを示し、 0 はキーが存在しないことを示します。 has_col_encoding テーブルのいずれかの列に対して圧縮エンコードが定義されているかどうかを示します。 1 は、少なくとも 1 つの列にエンコードが定義されていることを示します。 0 は、エンコードが定義されていないことを示します。 pct_skew_across_slices データ分散スキューの割合。値が小さいほど結果は良好です。 pct_slices_populated 入力されているスライスの割合。値が大きいほど結果は良好です。 --- ### RDS Oracleで拡張Varchar型の設定を行う date: 2021-05-06 url: https://zatoima.github.io/oracle-rds-for-oracle-extended-varchar2-setting.html tags: Oracle, RDS 拡張データ型で、ユーザーは VARCHAR2、NVARCHAR2、RAW コラムを最大 32767 バイトのサイズ(デフォルト:4000バイト)に拡大できるという機能があり、その機能をRDS Oracleで設定する方法をメモ。 データベースのスナップショットを作成 パラメータグループ内の MAX_STRING_SIZE パラメータを EXTENDED に設定 DB インスタンスを修正して MAX_STRING_SIZE を EXTENDED に設定したパラメータグループと関連付け DB再起動 パラメータ確認 SQL> show parameters max_string_size NAME TYPE ------------------------------------ --------------------------------- VALUE ------------------------------ max_string_size string EXTENDED SQL> データベースをupgradeモードにしたり、utl32k.sqlの実行がないので、オンプレミスよりも手順が簡略化されている。 Oracle 19cで拡張VARCHAR2型を導入 | my opinion is my own https://zatoima.github.io/oracle-19c-extended-varchar2.html 参照 Oracle DB インスタンスのその他のタスクの実行 - Amazon Relational Database Service https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Appendix.Oracle.CommonDBATasks.Misc.html#Oracle.Concepts.ExtendedDataTypes 拡張データ型を有効にする --- ### RDS Oracleでロックされているテーブルのセッションをkill date: 2021-05-05 url: https://zatoima.github.io/oracle-rds-for-oracle-kill-session.html tags: Oracle, RDS 息をするようにalter system kill sessionで殺していたセッションもRDSであれば専用のパッケージを使わないとダメで忘れがちなので備忘のためメモ。 SELECT X.SID , X.SERIAL# , TO_CHAR( X.SQL_EXEC_START , 'YYYY/MM/DD HH24:MI:SS' ) AS SQL_EXEC_START , Y.SQL_TEXT FROM V$SESSION X INNER JOIN V$SQL Y ON Y.HASH_VALUE = X.SQL_HASH_VALUE AND Y.ADDRESS = X.SQL_ADDRESS WHERE X.STATUS = 'ACTIVE' AND X.SID IN ( SELECT Z.SID FROM V$LOCK Z WHERE Z.TYPE IN ('TM','TX') ) ; exec rdsadmin.rdsadmin_util.kill(SID,SERIAL#); 実行結果 SQL> SELECT X.SID , X.SERIAL# , TO_CHAR( X.SQL_EXEC_START , 'YYYY/MM/DD HH24:MI:SS' ) AS SQL_EXEC_START , Y.SQL_TEXT FROM V$SESSION X INNER JOIN V$SQL Y ON Y.HASH_VALUE = X.SQL_HASH_VALUE AND Y.ADDRES 2 3 4 5 6 7 8 9 10 11 12 13 S = X.SQL_ADDRESS WHERE X.STATUS = 'ACTIVE' AND X.SID IN ( SELECT Z.SID FROM V$LOCK Z WHERE Z.TYPE IN ('TM','TX') ) ; 14 15 16 17 18 19 20 21 22 23 24 SID SERIAL# SQL_EXEC_START ---------- ---------- ------------------- SQL_TEXT -------------------------------------------------------------------------------- 1292 50094 2021/04/23 06:41:41 insert into PARTTBL_MAIN_1 select * from PARTTBL_MAIN_1 SQL> exec rdsadmin.rdsadmin_util.kill(1292,50094); PL/SQL procedure successfully completed. --- ### パワーポイント(pptx)ファイルをPythonでPDF化 date: 2021-05-01 url: https://zatoima.github.io/python-pptx-to-pdf.html tags: python, その他 手順 Windowsで実施。 必要なライブラリをインストール pip install comtypes git clone git clone https://github.com/matthewrenze/powerpoint-to-pdf.git pdf化したいpptxファイルをpowerpoint-to-pdfフォルダ配下に配置する python 実行 python ConvertHere.py 補足 ファイル指定:Convert.py フォルダ指定:ConvertAll.py カレントディレクトリ一式:ConvertHere.py (今回使用したスクリプト) 参考 from https://github.com/matthewrenze/powerpoint-to-pdf --- ### OracleとPostgreSQLのシーケンスキャッシュの動作差異 date: 2021-04-30 url: https://zatoima.github.io/oracle-postgresql-sequence-cache-incompatible.html tags: Oracle, PostgreSQL, DB Migration OracleとPostgreSQLのシーケンスキャッシュを使用した場合の動作差異についてメモ。PostgreSQLのcacheはデフォルト1なので、変更しない限りは同じような採番になると思われるが、実際はそうはならない。ここではPostgreSQLのCache値を変更した場合の注意点を記載。 シーケンスの作成 OracleとPostgreSQL両方ともシーケンスの始まりを「1」、キャッシュを「20」と設定。 Oracle drop sequence oraseq1; create sequence oraseq1 start with 1 increment by 1 cache 20; PostgreSQL drop sequence pgsqlseq1; create sequence pgsqlseq1 start with 1 increment by 1 cache 20; Oracle環境での動作 Session A select oraseq1.nextval from dual; 結果は当然シーケンス値は「1」となる。 SQL> select oraseq1.nextval from dual; NEXTVAL ---------- 1 Session B select oraseq1.nextval from dual; 別セッションでシーケンスを取得する場合、Oracleではnextvalもcurrvalが「2」となる。※ここの動作がOracleとPostgreSQLが異なる SQL> select oraseq1.nextval from dual; NEXTVAL ---------- 2 Session A select oraseq1.nextval from dual; SQL> select oraseq1.nextval from dual; NEXTVAL ---------- 3 PostgreSQL環境での動作 Session A select nextval('pgsqlseq1'); postgres> select nextval('pgsqlseq1'); +-----------+ | nextval | |-----------| | 1 | +-----------+ Session B select nextval('pgsqlseq1'); postgres> select nextval('pgsqlseq1'); +-----------+ | nextval | |-----------| | 21 | +-----------+ Session A select nextval('pgsqlseq1'); postgres> select nextval('pgsqlseq1'); +-----------+ | nextval | |-----------| | 2 | +-----------+ 結果 start 1、cache 20のシーケンスでnextvalを実行した場合のシーケンス値について こうなる。※OracleはOrderオプション指定無しを前提 実行順序 セッション Oracle PostgreSQL ↓ Session A 1 1 ↓ Session B 2 21 ↓ Session A 3 2 最後に Oracleでは特定事象が起きないとシーケンスは飛び番にはならないと思っているが、Cache値をデフォルトから変更すると、PostgreSQLは安易に起こりうる。**連番ではなく、一意を保証という点でで使うべき**である。そもそもキャッシュしている時点で連番になることを保証するのはOracleでも難しいはず。Oracleのインスタンス障害や共有プールからのエージアウト等があった場合にはキャッシュ分は飛ぶので。 下記の通り、マニュアルでも欠番のないシーケンス用途では使えないと書かれている。トランザクションのロールバックを行った場合、nextval や setval はロールバックされないので欠番になるし、再起動にもメモリ上に格納されたキャッシュは消えてしまう。 9.17. シーケンス操作関数 https://www.postgresql.jp/document/13/html/functions-sequence.html 従って、PostgreSQLのシーケンスオブジェクトは*「欠番のない」シーケンスを得るために使うことはできません*。 CREATE SEQUENCE https://www.postgresql.jp/document/13/html/sql-createsequence.html nextvalとsetvalの呼び出しは決してロールバックされないので、シーケンスの番号について「欠番のない」割り当てが必要な場合には、シーケンスオブジェクトを使うことはできません。 --- ### Oracle Partiotionオプションの代替策(View+Trigger)を試してみる date: 2021-04-27 url: https://zatoima.github.io/oracle-ee-se2-partition-trigger-view.html tags: Oracle, EE, SE2, RDS はじめに 下記に検討した内容の続きとして、Oracle Partitionの代替案というのをやってみた。 Oracle Enterprise EditionからStandard Editionへのダウングレード検討メモ | my opinion is my own https://zatoima.github.io/oracle-ee-se2-migration-to-aws-rds-for-oracle.html 大規模テーブルや履歴データなどはパーティション機能を使うことはよくあるが、Oracle EEからSE2へのダウングレードを検討する場合は、Partitionオプションを使用できないため、どうにかする必要がある。 パーティションを使う理由というのはいくつかあって、下記が代表的なメリットとして考えられる。 パーティションプルーニングを行うことでの性能向上 パーティション単位でパラレル化出来ることによる性能向上 複数パーティションに跨って検索する場合に有効 パーティション単位でドロップ出来ることでの運用性向上 これが出来ない場合は、DELETE文を発行する必要があり、IO的にも時間的にも厳しい 少し調べてみるといくつかの代替策が見つかったので、今回はその代替案を実施してみる。参考にしたのはこのあたり。この記事では疑似パーティションと呼ぶ Implementing table partitioning in Oracle Standard Edition: Part 1 | AWS Database Blog https://aws.amazon.com/jp/blogs/database/implementing-table-partitioning-in-oracle-standard-edition-part-1/ Partitioning and Oracle Standard Edition | Oracle FAQ https://www.orafaq.com/node/2992 Oracle Partitioning and Standard Edition | the gruffdba https://gruffdba.wordpress.com/2018/08/05/oracle-partitioning-and-standard-edition/ Oracle SEでINSERT TRIGGERとVIEWで作るパーティション - kenken0807_DBメモ https://kenken0807.hatenablog.com/entry/2015/07/21/161333 パーティション代替の仕組みのイメージ図 下記の図に書いている通り、TriggerとViewを使用した代替案となる。この方法はOracleでPartitionが実装されている前(Oracle 7時代?)はこの方法であり、PostgreSQLの9.6以前は継承とトリガーを使った方式になっていてこのイメージ図に近い。 疑似パーティションテーブル郡を増やす場合には、TableやView定義、及びTriggerの修正が必要となってくるので運用面で大丈夫かは別途確認する必要がある。 ポイントとしては次の通り(ここではレンジパーティションをイメージ) 各年月単位に区切ったデータが入るテーブルを複数用意する SELECTやDML(INSERT、UPDATED、DELETE)の対象先テーブルはVIEWとなる VIEWは各テーブルをUNION ALLでJOINした定義とする DML(ここではINSERT)が飛んできた時にTriggerを起動し、対象の年月がどのパーティションに入るべきかをIF文、CASE文等で判別し、各テーブルに入れる VIEWに索引付与ということは出来ないので、必然的にローカル索引となる。(=パーティションで使用出来ていたグローバル索引は付与出来ない) パーティションキーにローカル索引を作成する 流れ この方法を試すにあたり、移行元(EEのパーティション表構成)と移行先の環境(疑似パーティション構成)での性能検証比較を主にやりたかったので下記の流れで実施する。 EEのパーティション表を使用 大容量テーブルを作ってEEのパーティション機能を使って性能の簡易検証を実施 パーティション有り無し、索引有り無しを検証 疑似パーティションを使用 環境構成は 1.EEのパーティション表を使用 と一緒。パーティション部分を疑似パーティション構成とする 疑似パーティション有り無し、索引有り無しを検証 EEのパーティション表を使用 環境作成からスタート ユーザ作成 drop user TESTPART; create user TESTPART identified by oracle; grant dba to TESTPART; conn testpart/oracle@rdsoraclev19c.xxxx.ap-northeast-1.rds.amazonaws.com:1521/ora19c パーティション有り、索引無しパターン パーティションテーブルを作成 CREATE TABLE PARTTEST_EE_PART( id number, ymd DATE, str1 VARCHAR(120), str2 VARCHAR(500), str3 VARCHAR2(10), str4 NUMBER(9,0) ) PARTITION BY RANGE(ymd) ( PARTITION ymd_p00 VALUES LESS THAN(TO_DATE('2010/01/01','YYYY/MM/DD')), PARTITION ymd_p01 VALUES LESS THAN(TO_DATE('2011/01/01','YYYY/MM/DD')), PARTITION ymd_p02 VALUES LESS THAN(TO_DATE('2012/01/01','YYYY/MM/DD')), PARTITION ymd_p03 VALUES LESS THAN(TO_DATE('2013/01/01','YYYY/MM/DD')), PARTITION ymd_p04 VALUES LESS THAN(TO_DATE('2014/01/01','YYYY/MM/DD')), PARTITION ymd_p05 VALUES LESS THAN(TO_DATE('2015/01/01','YYYY/MM/DD')), PARTITION ymd_p06 VALUES LESS THAN(TO_DATE('2016/01/01','YYYY/MM/DD')), PARTITION ymd_p07 VALUES LESS THAN(TO_DATE('2017/01/01','YYYY/MM/DD')), PARTITION ymd_p08 VALUES LESS THAN(TO_DATE('2018/01/01','YYYY/MM/DD')), PARTITION ymd_p09 VALUES LESS THAN(TO_DATE('2019/01/01','YYYY/MM/DD')), PARTITION ymd_p10 VALUES LESS THAN(TO_DATE('2020/01/01','YYYY/MM/DD')), PARTITION ymd_p11 VALUES LESS THAN(TO_DATE('2021/01/01','YYYY/MM/DD')) ); 100万件のデータ作成 INSERT /*+ APPEND */ INTO PARTTEST_EE_PART NOLOGGING SELECT parttest_seq.nextval, TO_DATE('20100101','YYYYMMDD') +MOD(ABS(DBMS_RANDOM.RANDOM()),TO_DATE('20200101','YYYYMMDD')-TO_DATE('20100101','YYYYMMDD')) DT ,DBMS_RANDOM.STRING('X', 50) ,'あいうえおかきくけこさしすせそ' ,TO_CHAR(ABS(DBMS_RANDOM.RANDOM()),'FM0000000000') CD ,MOD(DBMS_RANDOM.RANDOM(),100000) KIN FROM (SELECT 0 FROM ALL_CATALOG WHERE ROWNUM <= 1000) ,(SELECT 0 FROM ALL_CATALOG WHERE ROWNUM <= 1000); commit; データをInsert ~ Selectで増幅(たくさん) insert into PARTTEST_EE_PART NOLOGGING select * from PARTTEST_EE_PART; commit; select count(*) from PARTTEST_EE_PART; 約1億件ちょっと SQL> select count(*) from PARTTEST_EE_PART; COUNT(*) ____________ 128000000 num_rowsを確認するために統計情報収集 exec DBMS_STATS.GATHER_TABLE_STATS(ownname=>'TESTPART',tabname=>'PARTTEST_EE_PART',cascade=>false,DEGREE =>4); パーティションごとの件数を確認 select TABLE_OWNER ,TABLE_NAME ,PARTITION_NAME ,NUM_ROWS from ALL_TAB_PARTITIONS where table_name='PARTTEST_EE_PART' order by TABLE_NAME; SQL> select 2 TABLE_OWNER 3 ,TABLE_NAME 4 ,PARTITION_NAME 5 ,NUM_ROWS 6 from 7 ALL_TAB_PARTITIONS 8 where table_name='PARTTEST_EE_PART' 9 order by 10 TABLE_NAME; TABLE_OWNER TABLE_NAME PARTITION_NAME NUM_ROWS ______________ ___________________ _________________ ___________ TESTPART PARTTEST_EE_PART YMD_P00 0 TESTPART PARTTEST_EE_PART YMD_P01 12830976 TESTPART PARTTEST_EE_PART YMD_P02 12804736 TESTPART PARTTEST_EE_PART YMD_P03 12837760 TESTPART PARTTEST_EE_PART YMD_P04 12809088 TESTPART PARTTEST_EE_PART YMD_P05 12786176 TESTPART PARTTEST_EE_PART YMD_P06 12755840 TESTPART PARTTEST_EE_PART YMD_P07 12817408 TESTPART PARTTEST_EE_PART YMD_P08 12797184 TESTPART PARTTEST_EE_PART YMD_P09 12803072 TESTPART PARTTEST_EE_PART YMD_P10 12757760 TESTPART PARTTEST_EE_PART YMD_P11 0 この環境で下記SQLをパーティションありなし、索引ありなしで時間を計測。2年分に跨るデータの件数を確認。 exec rdsadmin.rdsadmin_util.flush_shared_pool; exec rdsadmin.rdsadmin_util.flush_buffer_cache; set autotrace on set timing on select count(*) from PARTTEST_EE_PART where ymd between to_date('2017/05/01 11:00:00','YYYY/MM/DD HH24:MI:SS') and to_date('2019/05/11 12:00:00','YYYY/MM/DD HH24:MI:SS'); 実行結果 SQL> select count(*) from PARTTEST_EE_PART where ymd between to_date('2017/05/01 11:00:00','YYYY/MM/DD HH24:MI:SS') and to_date('2019/05/11 12:00:00','YYYY/MM/DD HH24:MI:SS'); COUNT(*) ___________ 25941120 Explain Plan ----------------------------------------------------------- PLAN_TABLE_OUTPUT _________________________________________________________________________________________________________________ Plan hash value: 2195020283 -------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | -------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 8 | 192K (1)| 00:00:08 | | | | 1 | SORT AGGREGATE | | 1 | 8 | | | | | | 2 | PARTITION RANGE ITERATOR| | 26M| 198M| 192K (1)| 00:00:08 | 9 | 11 | |* 3 | TABLE ACCESS FULL | PARTTEST_EE_PART | 26M| 198M| 192K (1)| 00:00:08 | 9 | 11 | -------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 3 - filter("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) Statistics ----------------------------------------------------------- 249 CPU used by this session 250 CPU used when call started 865 DB time 3 Requests to/from client 10 enqueue releases 10 enqueue requests 5028 non-idle wait count 621 non-idle wait time 200 opened cursors cumulative 1 opened cursors current 5567 physical read total IO requests 5504 physical read total multi block requests 1 pinned cursors current 9 process last non-idle time 460 recursive calls 2 recursive cpu usage 701356 session logical reads 621 user I/O wait time 4 user calls Elapsed: 00:00:08.748 SQL> パーティション無し、索引無しパターン 非パーティション表を作成して、データを同一とする CREATE TABLE PARTTEST_EE_NONPART( id number, ymd DATE, str1 VARCHAR(120), str2 VARCHAR(500), str3 VARCHAR2(10), str4 NUMBER(9,0) ); insert into PARTTEST_EE_NONPART NOLOGGING select * from PARTTEST_EE_PART; select count(*) from PARTTEST_EE_PART; 時間を計測 exec rdsadmin.rdsadmin_util.flush_shared_pool; exec rdsadmin.rdsadmin_util.flush_buffer_cache; set autotrace on set timing on select count(*) from PARTTEST_EE_NONPART where ymd between to_date('2017/05/01 11:00:00','YYYY/MM/DD HH24:MI:SS') and to_date('2019/05/11 12:00:00','YYYY/MM/DD HH24:MI:SS'); SQL> select count(*) from PARTTEST_EE_NONPART where ymd between to_date('2017/05/01 11:00:00','YYYY/MM/DD HH24:MI:SS') and to_date('2019/05/11 12:00:00','YYYY/MM/DD HH24:MI:SS'); COUNT(*) ___________ 25941120 Explain Plan ----------------------------------------------------------- PLAN_TABLE_OUTPUT _____________________________________________________________________________________________ Plan hash value: 3084685461 ------------------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | 8 | 635K (1)| 00:00:25 | | 1 | SORT AGGREGATE | | 1 | 8 | | | |* 2 | TABLE ACCESS FULL| PARTTEST_EE_NONPART | 26M| 198M| 635K (1)| 00:00:25 | ------------------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) Statistics ----------------------------------------------------------- 1077 CPU used by this session 1078 CPU used when call started 3105 DB time 3 Requests to/from client 5 enqueue releases 5 enqueue requests 15184 non-idle wait count 2045 non-idle wait time 42 opened cursors cumulative 1 opened cursors current 18335 physical read total IO requests 18288 physical read total multi block requests 1 pinned cursors current 31 process last non-idle time 115 recursive calls 4667336 session logical reads 2045 user I/O wait time 4 user calls Elapsed: 00:00:31.136 パーティション有り、索引有りパターン 索引作成 drop index PARTTEST_EE_PART_IDX; create index PARTTEST_EE_PART_IDX ON PARTTEST_EE_PART(ymd) local nologging parallel 4; 実行結果 SQL> set autotrace on Autotrace Enabled Shows the execution plan as well as statistics of the statement. SQL> set timing on SQL> select count(*) from PARTTEST_EE_PART where ymd between to_date('2017/05/01 11:00:00','YYYY/MM/DD HH24:MI:SS') and to_date('2019/05/11 12:00:00','YYYY/MM/DD HH24:MI:SS'); COUNT(*) ___________ 25941120 Explain Plan ----------------------------------------------------------- PLAN_TABLE_OUTPUT ________________________________________________________________________________________________________________________________________________________ Plan hash value: 2795901320 ----------------------------------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib | ----------------------------------------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 8 | 69179 (1)| 00:00:03 | | | | | | | 1 | SORT AGGREGATE | | 1 | 8 | | | | | | | | | 2 | PX COORDINATOR | | | | | | | | | | | | 3 | PX SEND QC (RANDOM) | :TQ10000 | 1 | 8 | | | | | Q1,00 | P->S | QC (RAND) | | 4 | SORT AGGREGATE | | 1 | 8 | | | | | Q1,00 | PCWP | | | 5 | PX PARTITION RANGE ITERATOR| | 26M| 198M| 69179 (1)| 00:00:03 | 9 | 11 | Q1,00 | PCWC | | |* 6 | INDEX RANGE SCAN | PARTTEST_EE_PART_IDX | 26M| 198M| 69179 (1)| 00:00:03 | 9 | 11 | Q1,00 | PCWP | | ----------------------------------------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 6 - access("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) Statistics ----------------------------------------------------------- 277 CPU used by this session 3 CPU used when call started 3654 DB time 3 Requests to/from client 6 enqueue conversions 18 enqueue releases 21 enqueue requests 1770 in call idle wait time 3 messages sent 68920 non-idle wait count 1704 non-idle wait time 318 opened cursors cumulative 1 opened cursors current 68894 physical read total IO requests 1 pinned cursors current 9 process last non-idle time 779 recursive calls 277 recursive cpu usage 69883 session logical reads 1703 user I/O wait time 16 user calls Elapsed: 00:00:09.506 パーティション無し、索引有りパターン drop index PARTTEST_EE_NONPART_IDX; create index PARTTEST_EE_NONPART_IDX ON PARTTEST_EE_NONPART(ymd) nologging parallel 4; 実行結果 SQL> select count(*) from PARTTEST_EE_NONPART where ymd between to_date('2017/05/01 11:00:00','YYYY/MM/DD HH24:MI:SS') and to_date('2019/05/11 12:00:00','YYYY/MM/DD HH24:MI:SS'); COUNT(*) ___________ 25941120 Explain Plan ----------------------------------------------------------- PLAN_TABLE_OUTPUT ________________________________________________________________________________________________ Plan hash value: 1281488453 --------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 9 | 76083 (1)| 00:00:03 | | 1 | SORT AGGREGATE | | 1 | 9 | | | |* 2 | INDEX RANGE SCAN| PARTTEST_EE_NONPART_IDX | 33M| 290M| 76083 (1)| 00:00:03 | --------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) Note ----- - dynamic statistics used: dynamic sampling (level=2) Statistics ----------------------------------------------------------- 236 CPU used by this session 237 CPU used when call started 2182 DB time 3 Requests to/from client 5 enqueue releases 5 enqueue requests 68838 non-idle wait count 2030 non-idle wait time 25 opened cursors cumulative 1 opened cursors current 68834 physical read total IO requests 1 pinned cursors current 22 process last non-idle time 82 recursive calls 1 recursive cpu usage 68890 session logical reads 2030 user I/O wait time 4 user calls Elapsed: 00:00:21.901 結果 パーティションあり パーティションなし 索引あり 9.506 21.901 索引なし 8.748 31.136 疑似パーティションを使用 環境作成からスタート 疑似パーティションのイメージ(再掲) パーティション表のイメージ 下記のようなパーティションを作りたい。(これを作るわけではない) CREATE TABLE PARTTEST_EE_PART( id number, ymd DATE, str1 VARCHAR(120), str2 VARCHAR(500), str3 VARCHAR2(10), str4 NUMBER(9,0) ) PARTITION BY RANGE(ymd) ( PARTITION ymd_p00 VALUES LESS THAN(TO_DATE('2010/01/01','YYYY/MM/DD')), PARTITION ymd_p01 VALUES LESS THAN(TO_DATE('2011/01/01','YYYY/MM/DD')), PARTITION ymd_p02 VALUES LESS THAN(TO_DATE('2012/01/01','YYYY/MM/DD')), PARTITION ymd_p03 VALUES LESS THAN(TO_DATE('2013/01/01','YYYY/MM/DD')), PARTITION ymd_p04 VALUES LESS THAN(TO_DATE('2014/01/01','YYYY/MM/DD')), PARTITION ymd_p05 VALUES LESS THAN(TO_DATE('2015/01/01','YYYY/MM/DD')), PARTITION ymd_p06 VALUES LESS THAN(TO_DATE('2016/01/01','YYYY/MM/DD')), PARTITION ymd_p07 VALUES LESS THAN(TO_DATE('2017/01/01','YYYY/MM/DD')), PARTITION ymd_p08 VALUES LESS THAN(TO_DATE('2018/01/01','YYYY/MM/DD')), PARTITION ymd_p09 VALUES LESS THAN(TO_DATE('2019/01/01','YYYY/MM/DD')), PARTITION ymd_p10 VALUES LESS THAN(TO_DATE('2020/01/01','YYYY/MM/DD')), PARTITION ymd_p11 VALUES LESS THAN(TO_DATE('2021/01/01','YYYY/MM/DD')) ); 表で対比する場合は下記の通り。 パーティション名 テーブル ymd_p00 PARTTEST_SE_PART_1 ymd_p01 PARTTEST_SE_PART_2 ymd_p02 PARTTEST_SE_PART_3 ymd_p03 PARTTEST_SE_PART_4 ymd_p04 PARTTEST_SE_PART_5 ymd_p05 PARTTEST_SE_PART_6 ymd_p06 PARTTEST_SE_PART_7 ymd_p07 PARTTEST_SE_PART_8 ymd_p08 PARTTEST_SE_PART_9 ymd_p09 PARTTEST_SE_PART_10 ymd_p10 PARTTEST_SE_PART_11 ymd_p11 PARTTEST_SE_PART_12 テーブル作成(=疑似パーティションテーブル郡) -- Partition like table 1 CREATE TABLE PARTTEST_SE_PART_1 ( id number, ymd DATE, str1 VARCHAR(120), str2 VARCHAR(500), str3 VARCHAR2(10), str4 NUMBER(9,0) ); -- Partition like table 2 CREATE TABLE PARTTEST_SE_PART_2 ( id number, ymd DATE, str1 VARCHAR(120), str2 VARCHAR(500), str3 VARCHAR2(10), str4 NUMBER(9,0) ); -- Partition like table 3 CREATE TABLE PARTTEST_SE_PART_3 ( id number, ymd DATE, str1 VARCHAR(120), str2 VARCHAR(500), str3 VARCHAR2(10), str4 NUMBER(9,0) ); -- Partition like table 4 CREATE TABLE PARTTEST_SE_PART_4 ( id number, ymd DATE, str1 VARCHAR(120), str2 VARCHAR(500), str3 VARCHAR2(10), str4 NUMBER(9,0) ); -- Partition like table 5 CREATE TABLE PARTTEST_SE_PART_5 ( id number, ymd DATE, str1 VARCHAR(120), str2 VARCHAR(500), str3 VARCHAR2(10), str4 NUMBER(9,0) ); -- Partition like table 6 CREATE TABLE PARTTEST_SE_PART_6 ( id number, ymd DATE, str1 VARCHAR(120), str2 VARCHAR(500), str3 VARCHAR2(10), str4 NUMBER(9,0) ); -- Partition like table 7 CREATE TABLE PARTTEST_SE_PART_7 ( id number, ymd DATE, str1 VARCHAR(120), str2 VARCHAR(500), str3 VARCHAR2(10), str4 NUMBER(9,0) ); -- Partition like table 8 CREATE TABLE PARTTEST_SE_PART_8 ( id number, ymd DATE, str1 VARCHAR(120), str2 VARCHAR(500), str3 VARCHAR2(10), str4 NUMBER(9,0) ); -- Partition like table 9 CREATE TABLE PARTTEST_SE_PART_9 ( id number, ymd DATE, str1 VARCHAR(120), str2 VARCHAR(500), str3 VARCHAR2(10), str4 NUMBER(9,0) ); -- Partition like table 10 CREATE TABLE PARTTEST_SE_PART_10 ( id number, ymd DATE, str1 VARCHAR(120), str2 VARCHAR(500), str3 VARCHAR2(10), str4 NUMBER(9,0) ); -- Partition like table 11 CREATE TABLE PARTTEST_SE_PART_11 ( id number, ymd DATE, str1 VARCHAR(120), str2 VARCHAR(500), str3 VARCHAR2(10), str4 NUMBER(9,0) ); -- Partition like table 12 CREATE TABLE PARTTEST_SE_PART_12 ( id number, ymd DATE, str1 VARCHAR(120), str2 VARCHAR(500), str3 VARCHAR2(10), str4 NUMBER(9,0) ); ビューを作成 CREATE VIEW PARTTEST_SE_PART AS SELECT * FROM PARTTEST_SE_PART_1 UNION ALL SELECT * FROM PARTTEST_SE_PART_2 UNION ALL SELECT * FROM PARTTEST_SE_PART_3 UNION ALL SELECT * FROM PARTTEST_SE_PART_4 UNION ALL SELECT * FROM PARTTEST_SE_PART_5 UNION ALL SELECT * FROM PARTTEST_SE_PART_6 UNION ALL SELECT * FROM PARTTEST_SE_PART_7 UNION ALL SELECT * FROM PARTTEST_SE_PART_8 UNION ALL SELECT * FROM PARTTEST_SE_PART_9 UNION ALL SELECT * FROM PARTTEST_SE_PART_10 UNION ALL SELECT * FROM PARTTEST_SE_PART_11 UNION ALL SELECT * FROM PARTTEST_SE_PART_12 / INSERT用のトリガーを作成 今回はINSERT用のトリガーしか作っていないが、DELETEやUPDATEも入って来る場合はDMLに応じたトリガーが必要。今回は擬似的にレンジパーティションに作っているが、疑似リストパーティション、おそらく疑似ハッシュパーティションも出来るはず。 CREATE OR REPLACE TRIGGER PARTTEST_SE_PART_INSERT INSTEAD OF INSERT ON PARTTEST_SE_PART FOR EACH ROW DECLARE n_part date; BEGIN n_part := :NEW.ymd; IF n_part between to_date('2009/01/01','YYYY/MM/DD') and to_date('2010/01/01','YYYY/MM/DD') THEN insert into PARTTEST_SE_PART_1 values(:new.id,:new.ymd,:new.str1,:new.str2,:new.str3,:new.str4); ELSIF n_part between to_date('2010/01/01','YYYY/MM/DD') and to_date('2010/12/31','YYYY/MM/DD') THEN insert into PARTTEST_SE_PART_2 values(:new.id,:new.ymd,:new.str1,:new.str2,:new.str3,:new.str4); ELSIF n_part between to_date('2011/01/01','YYYY/MM/DD') and to_date('2011/12/31','YYYY/MM/DD') THEN insert into PARTTEST_SE_PART_3 values(:new.id,:new.ymd,:new.str1,:new.str2,:new.str3,:new.str4); ELSIF n_part between to_date('2012/01/01','YYYY/MM/DD') and to_date('2012/12/31','YYYY/MM/DD') THEN insert into PARTTEST_SE_PART_4 values(:new.id,:new.ymd,:new.str1,:new.str2,:new.str3,:new.str4); ELSIF n_part between to_date('2013/01/01','YYYY/MM/DD') and to_date('2013/12/31','YYYY/MM/DD') THEN insert into PARTTEST_SE_PART_5 values(:new.id,:new.ymd,:new.str1,:new.str2,:new.str3,:new.str4); ELSIF n_part between to_date('2014/01/01','YYYY/MM/DD') and to_date('2014/12/31','YYYY/MM/DD') THEN insert into PARTTEST_SE_PART_6 values(:new.id,:new.ymd,:new.str1,:new.str2,:new.str3,:new.str4); ELSIF n_part between to_date('2015/01/01','YYYY/MM/DD') and to_date('2015/12/31','YYYY/MM/DD') THEN insert into PARTTEST_SE_PART_7 values(:new.id,:new.ymd,:new.str1,:new.str2,:new.str3,:new.str4); ELSIF n_part between to_date('2016/01/01','YYYY/MM/DD') and to_date('2016/12/31','YYYY/MM/DD') THEN insert into PARTTEST_SE_PART_8 values(:new.id,:new.ymd,:new.str1,:new.str2,:new.str3,:new.str4); ELSIF n_part between to_date('2017/01/01','YYYY/MM/DD') and to_date('2017/12/31','YYYY/MM/DD') THEN insert into PARTTEST_SE_PART_9 values(:new.id,:new.ymd,:new.str1,:new.str2,:new.str3,:new.str4); ELSIF n_part between to_date('2018/01/01','YYYY/MM/DD') and to_date('2018/12/31','YYYY/MM/DD') THEN insert into PARTTEST_SE_PART_10 values(:new.id,:new.ymd,:new.str1,:new.str2,:new.str3,:new.str4); ELSIF n_part between to_date('2019/01/01','YYYY/MM/DD') and to_date('2019/12/31','YYYY/MM/DD') THEN insert into PARTTEST_SE_PART_11 values(:new.id,:new.ymd,:new.str1,:new.str2,:new.str3,:new.str4); ELSIF n_part between to_date('2020/01/01','YYYY/MM/DD') and to_date('2020/12/31','YYYY/MM/DD') THEN insert into PARTTEST_SE_PART_12 values(:new.id,:new.ymd,:new.str1,:new.str2,:new.str3,:new.str4); END IF; END; / INSERTテスト 試しに1件だけビューに対してINSERTを実施してみる。 insert into PARTTEST_SE_PART values(1,TO_DATE('2012/01/01','YYYY/MM/DD'),DBMS_RANDOM.STRING('X', 50),'あああああ','AAAA',1); SQL> insert into PARTTEST_SE_PART values(1,TO_DATE('2012/01/01','YYYY/MM/DD'),DBMS_RANDOM.STRING('X', 50),'あああああ','AAAA',1); 1 row inserted. Elapsed: 00:00:00.092 SQL> commit; Commit complete. Elapsed: 00:00:00.004 SQL> select * from PARTTEST_SE_PART; ID YMD STR1 STR2 STR3 STR4 _____ ____________ _____________________________________________________ ________ _______ _______ 1 01-JAN-12 XDB01K5LVWKZC5KH5XRRV6Z2UAGU40I3U06ZPQ1H0JV5H7RGEC あああああ AAAA 1 Elapsed: 00:00:00.113 SQL> ビューとテーブルの件数を確認 select 'PARTTEST_SE_PART',count(*) rowcount from PARTTEST_SE_PART union all select 'PARTTEST_SE_PART_1',count(*) rowcount from PARTTEST_SE_PART_1 union all select 'PARTTEST_SE_PART_2',count(*) rowcount from PARTTEST_SE_PART_2 union all select 'PARTTEST_SE_PART_3',count(*) rowcount from PARTTEST_SE_PART_3 union all select 'PARTTEST_SE_PART_4',count(*) rowcount from PARTTEST_SE_PART_4 union all select 'PARTTEST_SE_PART_5',count(*) rowcount from PARTTEST_SE_PART_5 union all select 'PARTTEST_SE_PART_6',count(*) rowcount from PARTTEST_SE_PART_6 union all select 'PARTTEST_SE_PART_7',count(*) rowcount from PARTTEST_SE_PART_7 union all select 'PARTTEST_SE_PART_8',count(*) rowcount from PARTTEST_SE_PART_8 union all select 'PARTTEST_SE_PART_9',count(*) rowcount from PARTTEST_SE_PART_9 union all select 'PARTTEST_SE_PART_10',count(*) rowcount from PARTTEST_SE_PART_10 union all select 'PARTTEST_SE_PART_11',count(*) rowcount from PARTTEST_SE_PART_11 union all select 'PARTTEST_SE_PART_12',count(*) rowcount from PARTTEST_SE_PART_12 ; 正常にパーティションテーブルに入っていることを確認 'PARTTEST_SE_PART' ROWCOUNT ______________________ ___________ PARTTEST_SE_PART 1 PARTTEST_SE_PART_1 0 PARTTEST_SE_PART_2 0 PARTTEST_SE_PART_3 0 PARTTEST_SE_PART_4 1 PARTTEST_SE_PART_5 0 PARTTEST_SE_PART_6 0 PARTTEST_SE_PART_7 0 PARTTEST_SE_PART_8 0 PARTTEST_SE_PART_9 0 PARTTEST_SE_PART_10 0 PARTTEST_SE_PART_11 0 PARTTEST_SE_PART_12 0 13 rows selected. データ作成 前半で検証したパーティションテーブルからデータを抽出する insert into /*+ PARALLEL (4)) */ PARTTEST_SE_PART_1 NOLLOGING SELECT * FROM PARTTEST_EE_PART PARTITION(ymd_p00); insert into /*+ PARALLEL (4)) */ PARTTEST_SE_PART_2 NOLLOGING SELECT * FROM PARTTEST_EE_PART PARTITION(ymd_p01); insert into /*+ PARALLEL (4)) */ PARTTEST_SE_PART_3 NOLLOGING SELECT * FROM PARTTEST_EE_PART PARTITION(ymd_p02); insert into /*+ PARALLEL (4)) */ PARTTEST_SE_PART_4 NOLLOGING SELECT * FROM PARTTEST_EE_PART PARTITION(ymd_p03); insert into /*+ PARALLEL (4)) */ PARTTEST_SE_PART_5 NOLLOGING SELECT * FROM PARTTEST_EE_PART PARTITION(ymd_p04); insert into /*+ PARALLEL (4)) */ PARTTEST_SE_PART_6 NOLLOGING SELECT * FROM PARTTEST_EE_PART PARTITION(ymd_p05); insert into /*+ PARALLEL (4)) */ PARTTEST_SE_PART_7 NOLLOGING SELECT * FROM PARTTEST_EE_PART PARTITION(ymd_p06); insert into /*+ PARALLEL (4)) */ PARTTEST_SE_PART_8 NOLLOGING SELECT * FROM PARTTEST_EE_PART PARTITION(ymd_p07); insert into /*+ PARALLEL (4)) */ PARTTEST_SE_PART_9 NOLLOGING SELECT * FROM PARTTEST_EE_PART PARTITION(ymd_p08); insert into /*+ PARALLEL (4)) */ PARTTEST_SE_PART_10 NOLLOGING SELECT * FROM PARTTEST_EE_PART PARTITION(ymd_p09); insert into /*+ PARALLEL (4)) */ PARTTEST_SE_PART_11 NOLLOGING SELECT * FROM PARTTEST_EE_PART PARTITION(ymd_p10); insert into /*+ PARALLEL (4)) */ PARTTEST_SE_PART_12 NOLLOGING SELECT * FROM PARTTEST_EE_PART PARTITION(ymd_p11); commit; データ件数の確認 select 'PARTTEST_SE_PART',count(*) rowcount from PARTTBL_MAIN union all select 'PARTTEST_SE_PART_1',count(*) rowcount from PARTTEST_SE_PART_1 union all select 'PARTTEST_SE_PART_2',count(*) rowcount from PARTTEST_SE_PART_2 union all select 'PARTTEST_SE_PART_3',count(*) rowcount from PARTTEST_SE_PART_3 union all select 'PARTTEST_SE_PART_4',count(*) rowcount from PARTTEST_SE_PART_4 union all select 'PARTTEST_SE_PART_5',count(*) rowcount from PARTTEST_SE_PART_5 union all select 'PARTTEST_SE_PART_6',count(*) rowcount from PARTTEST_SE_PART_6 union all select 'PARTTEST_SE_PART_7',count(*) rowcount from PARTTEST_SE_PART_7 union all select 'PARTTEST_SE_PART_8',count(*) rowcount from PARTTEST_SE_PART_8 union all select 'PARTTEST_SE_PART_9',count(*) rowcount from PARTTEST_SE_PART_9 union all select 'PARTTEST_SE_PART_10',count(*) rowcount from PARTTEST_SE_PART_10 union all select 'PARTTEST_SE_PART_11',count(*) rowcount from PARTTEST_SE_PART_11 union all select 'PARTTEST_SE_PART_12',count(*) rowcount from PARTTEST_SE_PART_12 ; 簡易性能検証 一つの疑似パーティションに約3000万件のデータで全体で1億2万件のデータが可能されている。 SQL> select 'PARTTEST_SE_PART',count(*) rowcount from PARTTBL_MAIN 2 union all 3 select 'PARTTEST_SE_PART_1',count(*) rowcount from PARTTEST_SE_PART_1 4 union all 5 select 'PARTTEST_SE_PART_2',count(*) rowcount from PARTTEST_SE_PART_2 6 union all 7 select 'PARTTEST_SE_PART_3',count(*) rowcount from PARTTEST_SE_PART_3 8 union all 9 select 'PARTTEST_SE_PART_4',count(*) rowcount from PARTTEST_SE_PART_4 10 union all 11 select 'PARTTEST_SE_PART_5',count(*) rowcount from PARTTEST_SE_PART_5 12 union all 13 select 'PARTTEST_SE_PART_6',count(*) rowcount from PARTTEST_SE_PART_6 14 union all 15 select 'PARTTEST_SE_PART_7',count(*) rowcount from PARTTEST_SE_PART_7 16 union all 17 select 'PARTTEST_SE_PART_8',count(*) rowcount from PARTTEST_SE_PART_8 18 union all 19 select 'PARTTEST_SE_PART_9',count(*) rowcount from PARTTEST_SE_PART_9 20 union all 21 select 'PARTTEST_SE_PART_10',count(*) rowcount from PARTTEST_SE_PART_10 22 union all 23 select 'PARTTEST_SE_PART_11',count(*) rowcount from PARTTEST_SE_PART_11 24 union all 25 select 'PARTTEST_SE_PART_12',count(*) rowcount from PARTTEST_SE_PART_12 26 ; 'PARTTEST_SE_PART' ROWCOUNT ______________________ _____________ PARTTEST_SE_PART 2017394688 PARTTEST_SE_PART_1 0 PARTTEST_SE_PART_2 12830976 PARTTEST_SE_PART_3 12804736 PARTTEST_SE_PART_4 12837760 PARTTEST_SE_PART_5 12809088 PARTTEST_SE_PART_6 12786176 PARTTEST_SE_PART_7 12755840 PARTTEST_SE_PART_8 12817408 PARTTEST_SE_PART_9 12797184 PARTTEST_SE_PART_10 12803072 PARTTEST_SE_PART_11 12757760 PARTTEST_SE_PART_12 0 13 rows selected. SQL> パーティション表でも疑似パーティションでもない普通のテーブルを作成 drop table PARTTEST_SE_NONPART; CREATE TABLE PARTTEST_SE_NONPART ( id number, ymd DATE, str1 VARCHAR(120), str2 VARCHAR(500), str3 VARCHAR2(10), str4 NUMBER(9,0) ); insert into /*+ PARALLEL (4)) */ PARTTEST_SE_NONPART NOLOGGING select * from PARTTEST_SE_PART; 疑似パーティション有り、索引無しパターン ここから実際に簡易的な性能検証を実施してみる。 exec rdsadmin.rdsadmin_util.flush_shared_pool; exec rdsadmin.rdsadmin_util.flush_buffer_cache; set autotrace on set timing on set pages 2000 lin 2000 select count(*) from PARTTEST_SE_PART where ymd between to_date('2017/05/01 11:00:00','YYYY/MM/DD HH24:MI:SS') and to_date('2019/05/11 12:00:00','YYYY/MM/DD HH24:MI:SS'); 実行結果 SQL> select count(*) from PARTTEST_SE_PART where ymd between to_date('2017/05/01 11:00:00','YYYY/MM/DD HH24:MI:SS') and to_date('2019/05/11 12:00:00','YYYY/MM/DD HH24:MI:SS'); COUNT(*) ___________ 25941120 Explain Plan ----------------------------------------------------------- PLAN_TABLE_OUTPUT _______________________________________________________________________________________________ Plan hash value: 2206839629 -------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 9 | 642K (1)| 00:00:26 | | 1 | SORT AGGREGATE | | 1 | 9 | | | | 2 | VIEW | PARTTEST_SE_PART | 27M| 239M| 642K (1)| 00:00:26 | | 3 | UNION-ALL | | | | | | |* 4 | TABLE ACCESS FULL| PARTTEST_SE_PART_1 | 1 | 9 | 2 (0)| 00:00:01 | |* 5 | TABLE ACCESS FULL| PARTTEST_SE_PART_2 | 2606 | 23454 | 64292 (1)| 00:00:03 | |* 6 | TABLE ACCESS FULL| PARTTEST_SE_PART_3 | 2606 | 23454 | 64298 (1)| 00:00:03 | |* 7 | TABLE ACCESS FULL| PARTTEST_SE_PART_4 | 2606 | 23454 | 64280 (1)| 00:00:03 | |* 8 | TABLE ACCESS FULL| PARTTEST_SE_PART_5 | 2606 | 23454 | 64293 (1)| 00:00:03 | |* 9 | TABLE ACCESS FULL| PARTTEST_SE_PART_6 | 2606 | 23454 | 64298 (1)| 00:00:03 | |* 10 | TABLE ACCESS FULL| PARTTEST_SE_PART_7 | 2606 | 23454 | 64269 (1)| 00:00:03 | |* 11 | TABLE ACCESS FULL| PARTTEST_SE_PART_8 | 2606 | 23454 | 64273 (1)| 00:00:03 | |* 12 | TABLE ACCESS FULL| PARTTEST_SE_PART_9 | 9594K| 82M| 64294 (1)| 00:00:03 | |* 13 | TABLE ACCESS FULL| PARTTEST_SE_PART_10 | 13M| 113M| 64287 (1)| 00:00:03 | |* 14 | TABLE ACCESS FULL| PARTTEST_SE_PART_11 | 5094K| 43M| 64294 (1)| 00:00:03 | |* 15 | TABLE ACCESS FULL| PARTTEST_SE_PART_12 | 1 | 9 | 2 (0)| 00:00:01 | -------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 4 - filter("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) 5 - filter("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) 6 - filter("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) 7 - filter("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) 8 - filter("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) 9 - filter("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) 10 - filter("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) 11 - filter("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) 12 - filter("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) 13 - filter("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) 14 - filter("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) 15 - filter("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) Note ----- - dynamic statistics used: dynamic sampling (level=2) Statistics ----------------------------------------------------------- 1600 CPU used by this session 1601 CPU used when call started 3853 DB time 42 Requests to/from client 30 enqueue releases 30 enqueue requests 19833 non-idle wait count 2523 non-idle wait time 210 opened cursors cumulative 1 opened cursors current 19782 physical read total IO requests 18766 physical read total multi block requests 38 process last non-idle time 444 recursive calls 8 recursive cpu usage 2340871 session logical reads 2524 user I/O wait time 43 user calls Elapsed: 00:00:39.026 SQL> 疑似パーティション無し、索引無しパターン exec rdsadmin.rdsadmin_util.flush_shared_pool; exec rdsadmin.rdsadmin_util.flush_buffer_cache; set autotrace on set timing on set pages 2000 lin 2000 select count(*) from PARTTEST_SE_NONPART where ymd between to_date('2017/05/01 11:00:00','YYYY/MM/DD HH24:MI:SS') and to_date('2019/05/11 12:00:00','YYYY/MM/DD HH24:MI:SS'); 実行結果 SQL> set timing on SQL> set pages 2000 lin 2000 SQL> select count(*) from PARTTEST_SE_NONPART where ymd between to_date('2017/05/01 11:00:00','YYYY/MM/DD HH24:MI:SS') and to_date('2019/05/11 12:00:00','YYYY/MM/DD HH24:MI:SS'); COUNT(*) ___________ 25941120 Explain Plan ----------------------------------------------------------- PLAN_TABLE_OUTPUT _____________________________________________________________________________________________ Plan hash value: 145121306 ------------------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | 9 | 635K (1)| 00:00:25 | | 1 | SORT AGGREGATE | | 1 | 9 | | | |* 2 | TABLE ACCESS FULL| PARTTEST_SE_NONPART | 36M| 314M| 635K (1)| 00:00:25 | ------------------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) Note ----- - dynamic statistics used: dynamic sampling (level=2) Statistics ----------------------------------------------------------- 818 CPU used by this session 819 CPU used when call started 3118 DB time 3 Requests to/from client 4 enqueue conversions 13 enqueue releases 13 enqueue requests 1 enqueue waits 15903 non-idle wait count 2319 non-idle wait time 50 opened cursors cumulative 1 opened cursors current 21147 physical read total IO requests 18288 physical read total multi block requests 1 pinned cursors current 32 process last non-idle time 142 recursive calls 7 recursive cpu usage 2339571 session logical reads 2319 user I/O wait time 4 user calls Elapsed: 00:00:31.506 SQL> 索引を使用 ローカル索引のように各疑似パーティションテーブルに索引を付ける。 create index PARTTEST_SE_PART_1_IDX ON PARTTEST_SE_PART_1(ymd) nologging parallel 4; create index PARTTEST_SE_PART_2_IDX ON PARTTEST_SE_PART_2(ymd) nologging parallel 4; create index PARTTEST_SE_PART_3_IDX ON PARTTEST_SE_PART_3(ymd) nologging parallel 4; create index PARTTEST_SE_PART_4_IDX ON PARTTEST_SE_PART_4(ymd) nologging parallel 4; create index PARTTEST_SE_PART_5_IDX ON PARTTEST_SE_PART_5(ymd) nologging parallel 4; create index PARTTEST_SE_PART_6_IDX ON PARTTEST_SE_PART_6(ymd) nologging parallel 4; create index PARTTEST_SE_PART_7_IDX ON PARTTEST_SE_PART_7(ymd) nologging parallel 4; create index PARTTEST_SE_PART_8_IDX ON PARTTEST_SE_PART_8(ymd) nologging parallel 4; create index PARTTEST_SE_PART_9_IDX ON PARTTEST_SE_PART_9(ymd) nologging parallel 4; create index PARTTEST_SE_PART_10_IDX ON PARTTEST_SE_PART_10(ymd) nologging parallel 4; create index PARTTEST_SE_PART_11_IDX ON PARTTEST_SE_PART_11(ymd) nologging parallel 4; create index PARTTEST_SE_PART_12_IDX ON PARTTEST_SE_PART_12(ymd) nologging parallel 4; create index PARTTEST_SE_NONPART_IDX ON PARTTEST_SE_NONPART(ymd) nologging parallel 4; 疑似パーティション有り、索引有りパターン exec rdsadmin.rdsadmin_util.flush_shared_pool; exec rdsadmin.rdsadmin_util.flush_buffer_cache; set autotrace on set timing on set pages 2000 lin 2000 select count(*) from PARTTEST_SE_PART where ymd between to_date('2017/05/01 11:00:00','YYYY/MM/DD HH24:MI:SS') and to_date('2019/05/11 12:00:00','YYYY/MM/DD HH24:MI:SS'); SQL> select count(*) from PARTTEST_SE_PART where ymd between to_date('2017/05/01 11:00:00','YYYY/MM/DD HH24:MI:SS') and to_date('2019/05/11 12:00:00','YYYY/MM/DD HH24:MI:SS'); COUNT(*) ___________ 25941120 Explain Plan ----------------------------------------------------------- PLAN_TABLE_OUTPUT _______________________________________________________________________________________________________________________________________ Plan hash value: 1340602939 ------------------------------------------------------------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib | ------------------------------------------------------------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | 9 | 28333 (1)| 00:00:02 | | | | | 1 | SORT AGGREGATE | | 1 | 9 | | | | | | | 2 | PX COORDINATOR | | | | | | | | | | 3 | PX SEND QC (RANDOM) | :TQ10000 | 1 | 9 | | | Q1,00 | P->S | QC (RAND) | | 4 | SORT AGGREGATE | | 1 | 9 | | | Q1,00 | PCWP | | | 5 | VIEW | PARTTEST_SE_PART | 27M| 239M| 28333 (1)| 00:00:02 | Q1,00 | PCWP | | | 6 | UNION-ALL | | | | | | Q1,00 | PCWP | | | 7 | PX SELECTOR | | | | | | Q1,00 | PCWP | | |* 8 | INDEX RANGE SCAN | PARTTEST_SE_PART_1_IDX | 1 | 9 | 0 (0)| 00:00:01 | Q1,00 | PCWP | | | 9 | PX SELECTOR | | | | | | Q1,00 | PCWP | | |* 10 | INDEX RANGE SCAN | PARTTEST_SE_PART_2_IDX | 1 | 9 | 2 (0)| 00:00:01 | Q1,00 | PCWP | | | 11 | PX SELECTOR | | | | | | Q1,00 | PCWP | | |* 12 | INDEX RANGE SCAN | PARTTEST_SE_PART_3_IDX | 1 | 9 | 2 (0)| 00:00:01 | Q1,00 | PCWP | | | 13 | PX SELECTOR | | | | | | Q1,00 | PCWP | | |* 14 | INDEX RANGE SCAN | PARTTEST_SE_PART_4_IDX | 1 | 9 | 2 (0)| 00:00:01 | Q1,00 | PCWP | | | 15 | PX SELECTOR | | | | | | Q1,00 | PCWP | | |* 16 | INDEX RANGE SCAN | PARTTEST_SE_PART_5_IDX | 1 | 9 | 2 (0)| 00:00:01 | Q1,00 | PCWP | | | 17 | PX SELECTOR | | | | | | Q1,00 | PCWP | | |* 18 | INDEX RANGE SCAN | PARTTEST_SE_PART_6_IDX | 1 | 9 | 2 (0)| 00:00:01 | Q1,00 | PCWP | | | 19 | PX SELECTOR | | | | | | Q1,00 | PCWP | | |* 20 | INDEX RANGE SCAN | PARTTEST_SE_PART_7_IDX | 1 | 9 | 2 (0)| 00:00:01 | Q1,00 | PCWP | | | 21 | PX SELECTOR | | | | | | Q1,00 | PCWP | | |* 22 | INDEX RANGE SCAN | PARTTEST_SE_PART_8_IDX | 1 | 9 | 2 (0)| 00:00:01 | Q1,00 | PCWP | | | 23 | PX BLOCK ITERATOR | | 9594K| 82M| 9447 (1)| 00:00:01 | Q1,00 | PCWC | | |* 24 | INDEX FAST FULL SCAN| PARTTEST_SE_PART_9_IDX | 9594K| 82M| 9447 (1)| 00:00:01 | Q1,00 | PCWP | | | 25 | PX BLOCK ITERATOR | | 13M| 113M| 9452 (1)| 00:00:01 | Q1,00 | PCWC | | |* 26 | INDEX FAST FULL SCAN| PARTTEST_SE_PART_10_IDX | 13M| 113M| 9452 (1)| 00:00:01 | Q1,00 | PCWP | | | 27 | PX BLOCK ITERATOR | | 5094K| 43M| 9419 (1)| 00:00:01 | Q1,00 | PCWC | | |* 28 | INDEX FAST FULL SCAN| PARTTEST_SE_PART_11_IDX | 5094K| 43M| 9419 (1)| 00:00:01 | Q1,00 | PCWP | | | 29 | PX SELECTOR | | | | | | Q1,00 | PCWP | | |* 30 | INDEX RANGE SCAN | PARTTEST_SE_PART_12_IDX | 1 | 9 | 0 (0)| 00:00:01 | Q1,00 | PCWP | | ------------------------------------------------------------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 8 - access("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) 10 - access("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) 12 - access("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) 14 - access("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) 16 - access("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) 18 - access("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) 20 - access("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) 22 - access("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) 24 - filter("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) 26 - filter("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) 28 - filter("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) 30 - access("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) Note ----- - dynamic statistics used: dynamic sampling (level=2) Statistics ----------------------------------------------------------- 472 CPU used by this session 6 CPU used when call started 709 DB time 3 Requests to/from client 8 enqueue conversions 50 enqueue releases 54 enqueue requests 148 in call idle wait time 2 messages sent 1320 non-idle wait count 93 non-idle wait time 273 opened cursors cumulative 1 opened cursors current 1290 physical read total IO requests 922 physical read total multi block requests 1 pinned cursors current 2 process last non-idle time 557 recursive calls 471 recursive cpu usage 113998 session logical reads 93 user I/O wait time 20 user calls Elapsed: 00:00:01.856 疑似パーティション無し、索引有りパターン exec rdsadmin.rdsadmin_util.flush_shared_pool; exec rdsadmin.rdsadmin_util.flush_buffer_cache; set autotrace on set timing on set pages 2000 lin 2000 select count(*) from PARTTEST_SE_NONPART where ymd between to_date('2017/05/01 11:00:00','YYYY/MM/DD HH24:MI:SS') and to_date('2019/05/11 12:00:00','YYYY/MM/DD HH24:MI:SS'); SQL> select count(*) from PARTTEST_SE_NONPART where ymd between to_date('2017/05/01 11:00:00','YYYY/MM/DD HH24:MI:SS') and to_date('2019/05/11 12:00:00','YYYY/MM/DD HH24:MI:SS'); COUNT(*) ___________ 25941120 Explain Plan ----------------------------------------------------------- PLAN_TABLE_OUTPUT _____________________________________________________________________________________________________________________________________ Plan hash value: 2697818807 ---------------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib | ---------------------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 9 | 93390 (1)| 00:00:04 | | | | | 1 | SORT AGGREGATE | | 1 | 9 | | | | | | | 2 | PX COORDINATOR | | | | | | | | | | 3 | PX SEND QC (RANDOM) | :TQ10000 | 1 | 9 | | | Q1,00 | P->S | QC (RAND) | | 4 | SORT AGGREGATE | | 1 | 9 | | | Q1,00 | PCWP | | | 5 | PX BLOCK ITERATOR | | 36M| 314M| 93390 (1)| 00:00:04 | Q1,00 | PCWC | | |* 6 | INDEX FAST FULL SCAN| PARTTEST_SE_NONPART_IDX | 36M| 314M| 93390 (1)| 00:00:04 | Q1,00 | PCWP | | ---------------------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 6 - filter("YMD">=TO_DATE(' 2017-05-01 11:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "YMD"<=TO_DATE(' 2019-05-11 12:00:00', 'syyyy-mm-dd hh24:mi:ss')) Note ----- - dynamic statistics used: dynamic sampling (level=2) Statistics ----------------------------------------------------------- 867 CPU used by this session 2 CPU used when call started 1853 DB time 3 Requests to/from client 8 enqueue conversions 16 enqueue releases 20 enqueue requests 1 enqueue waits 404 in call idle wait time 2 messages sent 1261 non-idle wait count 577 non-idle wait time 49 opened cursors cumulative 1 opened cursors current 2774 physical read total IO requests 2711 physical read total multi block requests 1 pinned cursors current 4 process last non-idle time 136 recursive calls 866 recursive cpu usage 344724 session logical reads 576 user I/O wait time 20 user calls Elapsed: 00:00:04.011 結果 疑似パーティション有り、索引有りパターンの場合はインデックスを使うことで高速に検索が可能だった。Predicate Informationを見れば分かる通り、インデックスを使ってAccess predicateになって不要な表を高速に処理している。(=読み込んでいるブロック数が少ない)Predicate Informationのaccessとfilterの違いは次の通り。accessとは、データに「アクセス」するために何かを使用していることを意味する。つまり、関連するデータにのみ「アクセス」する。filterとは、必要以上のデータを取得し、取得後にフィルタリングする。フィルタはすべての行に適用され、フィルタを通過した行のみが送信される。 (あと、疑似パーティションなし/索引ありのパターンにおいて、オプティマイザの気持ちになれず、INDEX FAST FULL SCANが走っている理由がパッと思いつかなかった。) 疑似パーティションあり 疑似パーティションなし 索引あり 1.856 4.011 索引なし 39.026 31.506 全体的な結果 今回のケースではパーティション構成と疑似パーティションで大きな違いが見られないどころか、疑似パーティションありの方がインデックスを使うことにより高速に処理出来た。ざっくりと疑似パーティション構成の動作や設定方法を理解出来たので一旦、検証メモとしては以上。運用面でどうするか、他の検索時にはどうなるか等検討は必要になるかと思う。 取得データ量やオプティマイザの実行計画次第で大きく性能値は変更されうるので一概に判断はしないが、運用面の検討も含めてPoCを経てパーティションオプションをどうするかを決めれば良いと感じた。 パーティションあり パーティションなし 索引あり 9.506 21.901 索引なし 8.748 31.136 疑似パーティションあり 疑似パーティションなし 索引あり 1.856 4.011 索引なし 39.026 31.506 --- ### OracleのリアルタイムSQL監視 date: 2021-04-25 url: https://zatoima.github.io/oracle-realtime-monitoring-sql.html tags: Oracle, RDS チューニングや解析時にAWR、ASHと並んで便利だと思っているリアルタイムSQL監視のメモ。実行中のSQLを自動で監視し、詳細な統計を取得出来る。パラレルクエリ、もしくは5秒以上のSQLであれば自動で収集されているが、ヒント文を付与することでも本機能を使用することが出来る。TEXTタイプとACTIVEタイプがある。 SQL実行 exec rdsadmin.rdsadmin_util.flush_shared_pool; exec rdsadmin.rdsadmin_util.flush_buffer_cache; set autotrace on set timing on select /*+ MONITOR */ count(*) from PARTTEST_EE_PART where ymd between to_date('2017/05/01 11:00:00','YYYY/MM/DD HH24:MI:SS') and to_date('2019/05/11 12:00:00','YYYY/MM/DD HH24:MI:SS'); SQL_IDの確認 SELECT sql_id, hash_value, substr(sql_text,1,40) sql_text FROM v$sql WHERE sql_text like 'select /*+ MONITOR */ count(*) from%'; リアルタイムSQL監視の実行 SET LONG 1000000 SET LONGC 1000000 SET LINESIZE 300; SET PAGESIZE 1000; VAR c_rep CLOB; EXEC :c_rep := DBMS_SQLTUNE.REPORT_SQL_MONITOR(sql_id => '4yd6vvn27rar4', TYPE => 'TEXT'); PRINT c_rep; 実行ログ SQL> select dbms_sqltune.report_sql_monitor(sql_id => '4yd6vvn27rar4', TYPE => 'TEXT') from dual; DBMS_SQLTUNE.REPORT_SQL_MONITOR(SQL_ID=>'4YD6VVN27RAR4',TYPE=>'TEXT') SQL Monitoring Report SQL Text ------------------------------ select /*+ MONITOR */ count(*) from PARTTEST_EE_PART where ymd between to_date('2017/05/01 11:00:00','YYYY/MM/DD HH24:MI:SS') and to_date('2019/05/11 12:00:00','YYYY/MM/DD HH24:MI:SS') Global Information ------------------------------ Status : DONE (ALL ROWS) Instance ID : 1 Session : TESTPART (1291:39506) SQL ID : 4yd6vvn27rar4 SQL Execution ID : 16777217 Execution Started : 04/25/2021 02:33:34 First Refresh Time : 04/25/2021 02:33:34 Last Refresh Time : 04/25/2021 02:33:39 Duration : 5s Module/Action : SQLcl/- Service : SYS$USERS Program : SQLcl Fetch Calls : 1 Global Stats ================================================= | Elapsed | Cpu | Other | Fetch | Buffer | | Time(s) | Time(s) | Waits(s) | Calls | Gets | ================================================= | 10 | 10 | 0.00 | 1 | 68826 | ================================================= Parallel Execution Details (DOP=3 , Servers Allocated=3) ========================================================================================== | Name | Type | Server# | Elapsed | Cpu | Other | Buffer | Wait Events | | | | | Time(s) | Time(s) | Waits(s) | Gets | (sample #) | ========================================================================================== | PX Coordinator | QC | | 0.00 | 0.00 | | 9 | | | p000 | Set 1 | 1 | 4.92 | 4.92 | | 33963 | | | p001 | Set 1 | 2 | 3.08 | 3.08 | | 22698 | | | p002 | Set 1 | 3 | 2.12 | 2.12 | 0.00 | 12156 | | ========================================================================================== SQL Plan Monitoring Details (Plan Hash Value=2795901320) ======================================================================================================================================================== | Id | Operation | Name | Rows | Cost | Time | Start | Execs | Rows | Activity | Activity Detail | | | | | (Estim) | | Active(s) | Active | | (Actual) | (%) | (# samples) | ======================================================================================================================================================== | 0 | SELECT STATEMENT | | | | 1 | +5 | 1 | 1 | | | | 1 | SORT AGGREGATE | | 1 | | 1 | +5 | 1 | 1 | | | | 2 | PX COORDINATOR | | | | 1 | +5 | 4 | 3 | | | | 3 | PX SEND QC (RANDOM) | :TQ10000 | 1 | | 4 | +2 | 3 | 3 | | | | 4 | SORT AGGREGATE | | 1 | | 4 | +2 | 3 | 3 | | | | 5 | PX PARTITION RANGE ITERATOR | | 26M | 69179 | 6 | +0 | 3 | 26M | | | | 6 | INDEX RANGE SCAN | PARTTEST_EE_PART_IDX | 26M | 69179 | 6 | +0 | 3 | 26M | | | ======================================================================================================================================================== Elapsed: 00:00:00.045 リアルタイムSQL監視の実行 spool sqlmon_active.html select dbms_sqltune.report_sql_monitor(sql_id => '4yd6vvn27rar4', TYPE => 'ACTIVE') from dual; spool off レポート 参照 複雑なSQLチューニングもラクにする!SQL監視機能とは https://www.oracle.com/technetwork/jp/ondemand/db-basic/d-16-ssqltuning-1448439-ja.pdf データベース操作の監視 https://docs.oracle.com/cd/F19136_01/tgsql/monitoring-database-operations.html#GUID-4048D00E-2635-42C8-A37D-71EFAC619062 --- ### Redshiftのサンプルデータベース(TICKIT)を作る date: 2021-04-21 url: https://zatoima.github.io/aws-redshift-sample-database-tickit.html tags: AWS, Redshift 毎回マニュアル見ている気がするので、DDLコマンド等のメモ。7 個のテーブルで構成されていて、そのうち 2 個はファクトテーブル、5 個はディメンションとなる。 サンプルデータベース - Amazon Redshift https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/c_sampledb.html データベース作成 create database TICKIT; tickitデータベースに接続しておく。 \c tickit; テーブル作成 create table users( userid integer not null distkey sortkey, username char(8), firstname varchar(30), lastname varchar(30), city varchar(30), state char(2), email varchar(100), phone char(14), likesports boolean, liketheatre boolean, likeconcerts boolean, likejazz boolean, likeclassical boolean, likeopera boolean, likerock boolean, likevegas boolean, likebroadway boolean, likemusicals boolean); create table venue( venueid smallint not null distkey sortkey, venuename varchar(100), venuecity varchar(30), venuestate char(2), venueseats integer); create table category( catid smallint not null distkey sortkey, catgroup varchar(10), catname varchar(10), catdesc varchar(50)); create table date( dateid smallint not null distkey sortkey, caldate date not null, day character(3) not null, week smallint not null, month character(5) not null, qtr character(5) not null, year smallint not null, holiday boolean default('N')); create table event( eventid integer not null distkey, venueid smallint not null, catid smallint not null, dateid smallint not null sortkey, eventname varchar(200), starttime timestamp); create table listing( listid integer not null distkey, sellerid integer not null, eventid integer not null, dateid smallint not null sortkey, numtickets smallint not null, priceperticket decimal(8,2), totalprice decimal(8,2), listtime timestamp); create table sales( salesid integer not null, listid integer not null distkey, sellerid integer not null, buyerid integer not null, eventid integer not null, dateid smallint not null sortkey, qtysold smallint not null, pricepaid decimal(8,2), commission decimal(8,2), saletime timestamp); 7テーブル作成している。 tickit=# \dt List of relations schema | name | type | owner --------+----------+-------+--------- public | category | table | awsuser public | date | table | awsuser public | event | table | awsuser public | listing | table | awsuser public | sales | table | awsuser public | users | table | awsuser public | venue | table | awsuser (7 rows) データロード サンプル用のデータの取得 wget https://docs.aws.amazon.com/ja_jp/redshift/latest/gsg/samples/tickitdb.zip unzip tickitdb.zip -d tickitdb ls -l tickitdb copyコマンドを使うので、S3にアップロードする。 aws s3 mb s3://20210420tickit aws s3 sync ./tickitdb/ s3://20210420tickit S3のバケットにデータが格納された [ec2-user@bastin ~]$ aws s3 ls s3://20210420tickit 2021-04-20 20:34:58 445838 allevents_pipe.txt 2021-04-20 20:34:58 5893626 allusers_pipe.txt 2021-04-20 20:34:58 465 category_pipe.txt 2021-04-20 20:34:58 14534 date2008_pipe.txt 2021-04-20 20:34:58 11585036 listings_pipe.txt 2021-04-20 20:34:58 11260097 sales_tab.txt 2021-04-20 20:34:58 7988 venue_pipe.txt データロードコマンド copy users from 's3://20210420tickit/allusers_pipe.txt' iam_role 'arn:aws:iam::xxxxxx:role/myRedshiftRole' delimiter '|'; copy venue from 's3://20210420tickit/venue_pipe.txt' iam_role 'arn:aws:iam::xxxxxx:role/myRedshiftRole' delimiter '|'; copy category from 's3://20210420tickit/category_pipe.txt' iam_role 'arn:aws:iam::xxxxxx:role/myRedshiftRole' delimiter '|'; copy date from 's3://20210420tickit/date2008_pipe.txt' iam_role 'arn:aws:iam::xxxxxx:role/myRedshiftRole' delimiter '|'; copy event from 's3://20210420tickit/allevents_pipe.txt' iam_role 'arn:aws:iam::xxxxxx:role/myRedshiftRole' delimiter '|' timeformat 'YYYY-MM-DD HH:MI:SS'; copy listing from 's3://20210420tickit/listings_pipe.txt' iam_role 'arn:aws:iam::xxxxxx:role/myRedshiftRole' delimiter '|'; copy sales from 's3://20210420tickit/sales_tab.txt' iam_role 'arn:aws:iam::xxxxxx:role/myRedshiftRole' delimiter '\t' timeformat 'MM/DD/YYYY HH:MI:SS'; テーブルごとの行数確認 [ec2-user@bastin AdminScripts]$ pwd /home/ec2-user/amazon-redshift-utils-master/src/AdminScripts [ec2-user@bastin AdminScripts]$ ls -l total 112 -rw-rw-r-- 1 ec2-user ec2-user 899 Mar 26 03:15 commit_stats.sql -rw-rw-r-- 1 ec2-user ec2-user 1163 Mar 26 03:15 copy_performance.sql -rw-rw-r-- 1 ec2-user ec2-user 527 Mar 26 03:15 current_session_info.sql -rw-rw-r-- 1 ec2-user ec2-user 1466 Mar 26 03:15 filter_used.sql -rw-rw-r-- 1 ec2-user ec2-user 2553 Mar 26 03:15 generate_calendar.sql -rw-rw-r-- 1 ec2-user ec2-user 1940 Mar 26 03:15 insert_into_table_dk_mismatch.sql -rw-rw-r-- 1 ec2-user ec2-user 3440 Mar 26 03:15 lock_wait.sql -rw-rw-r-- 1 ec2-user ec2-user 309 Mar 26 03:15 missing_table_stats.sql -rw-rw-r-- 1 ec2-user ec2-user 2312 Mar 26 03:15 perf_alert.sql -rw-rw-r-- 1 ec2-user ec2-user 2389 Mar 26 03:15 predicate_columns.sql -rw-rw-r-- 1 ec2-user ec2-user 3019 Mar 26 03:15 queue_resources_hourly.sql -rw-rw-r-- 1 ec2-user ec2-user 787 Mar 26 03:15 queuing_queries.sql -rw-rw-r-- 1 ec2-user ec2-user 3279 Mar 26 03:15 README.md -rw-rw-r-- 1 ec2-user ec2-user 2978 Mar 26 03:15 running_queues.sql -rw-rw-r-- 1 ec2-user ec2-user 2054 Mar 26 03:15 table_alerts.sql -rw-rw-r-- 1 ec2-user ec2-user 4584 Mar 26 03:15 table_info.sql -rw-rw-r-- 1 ec2-user ec2-user 1688 Mar 26 03:15 table_inspector.sql -rw-rw-r-- 1 ec2-user ec2-user 3504 Mar 26 03:15 top_queries_and_cursors.sql -rw-rw-r-- 1 ec2-user ec2-user 2431 Mar 26 03:15 top_queries.sql -rw-rw-r-- 1 ec2-user ec2-user 3060 Mar 26 03:15 unscanned_table_summary.sql -rw-rw-r-- 1 ec2-user ec2-user 1876 Mar 26 03:15 user_to_be_dropped_objs.sql -rw-rw-r-- 1 ec2-user ec2-user 5410 Mar 26 03:15 user_to_be_dropped_privs.sql -rw-rw-r-- 1 ec2-user ec2-user 2876 Mar 26 03:15 wlm_apex_hourly.sql -rw-rw-r-- 1 ec2-user ec2-user 3302 Mar 26 03:15 wlm_apex.sql -rw-rw-r-- 1 ec2-user ec2-user 7567 Mar 26 03:15 wlm_qmr_rule_candidates.sql [ec2-user@bastin AdminScripts]$ psql -h redshift-cluster.ciwori21oiel.ap-northeast-1.redshift.amazonaws.com -U awsuser -d tickit -p 5439 psql (11.5, server 8.0.2) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) Type "help" for help. tickit=# \i table_info.sql schema | table | tableid | distkey | skew | sortkey | #sks | rows | mbytes | enc | pct_enc | pct_of_total | pct_stats_off | pct_unsorted --------+----------+---------+---------+--------+---------+------+--------+--------+-----+-----------------------+--------------+---------------+-------------- public | users | 203862 | userid | 1.0000 | userid | 1 | 49990 | 168 | Y | 33.333333333333333300 | 0.00 | 0.00 | 0.00 public | sales | 203875 | listid | 1.0000 | dateid | 1 | 172456 | 104 | Y | 57.894736842105263100 | 0.00 | 0.00 | 0.00 public | date | 203868 | dateid | 1.0000 | dateid | 1 | 365 | 88 | Y | 47.058823529411764700 | 0.00 | 0.00 | 0.00 public | listing | 203873 | listid | 1.0000 | dateid | 1 | 192497 | 88 | Y | 52.941176470588235200 | 0.00 | 0.00 | 0.00 public | event | 203871 | eventid | 1.0000 | dateid | 1 | 8798 | 72 | Y | 46.666666666666666600 | 0.00 | 0.00 | 0.00 public | venue | 203864 | venueid | 1.0000 | venueid | 1 | 202 | 64 | Y | 42.857142857142857100 | 0.00 | 0.00 | 0.00 public | category | 203866 | catid | 1.0000 | catid | 1 | 11 | 56 | Y | 38.461538461538461500 | 0.00 | 0.00 | 0.00 (7 rows) tickit=# サンプルクエリとして用意されているものだが、2008 年に販売されたチケット数に基づき、サンディエゴで最も販売数の多かった販売者 5 名を検出 select sellerid, username, (firstname ||' '|| lastname) as name, city, sum(qtysold) from sales, date, users where sales.sellerid = users.userid and sales.dateid = date.dateid and year = 2008 and city = 'San Diego' group by sellerid, username, name, city order by 5 desc limit 5; tickit=# select sellerid, username, (firstname ||' '|| lastname) as name, tickit-# city, sum(qtysold) tickit-# from sales, date, users tickit-# where sales.sellerid = users.userid tickit-# and sales.dateid = date.dateid tickit-# and year = 2008 tickit-# and city = 'San Diego' tickit-# group by sellerid, username, name, city tickit-# order by 5 desc tickit-# limit 5; sellerid | username | name | city | sum ----------+----------+-------------------+-----------+----- 49977 | JJK84WTE | Julie Hanson | San Diego | 22 19750 | AAS23BDR | Charity Zimmerman | San Diego | 21 29069 | SVL81MEQ | Axel Grant | San Diego | 17 43632 | VAG08HKW | Griffin Dodson | San Diego | 16 18888 | KMQ52NVN | Joan Wright | San Diego | 14 (5 rows) tickit=# 参考 サンプルデータベース - Amazon Redshift https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/c_sampledb.html ステップ 6: Amazon S3 のサンプルデータをロードする - Amazon Redshift https://docs.aws.amazon.com/ja_jp/redshift/latest/gsg/rs-gsg-create-sample-db.html --- ### RedshiftのS3へのデータアンロード date: 2021-04-20 url: https://zatoima.github.io/aws-data-unload-redshift-to-s3.html tags: AWS, Redshift パラレルモードオン S3のバケットにノードスライスごとにファイルが生成される ノードスライス分、高速にアンロードが可能 unload ('select * from unloadtest') to 's3://dataforrs/test20210405/unloadtest_' iam_role 'arn:aws:iam::xxxxx:role/myRedshiftRole' header format csv gzip allowoverwrite; ログ mydb=# unload ('select * from unloadtest') mydb-# to 's3://unloadtest/test20210405/unloadtest_' mydb-# iam_role 'arn:aws:iam::xx:role/myRedshiftRole' mydb-# header mydb-# format csv mydb-# gzip mydb-# allowoverwrite; INFO: UNLOAD completed, 87701667 record(s) unloaded successfully. UNLOAD Time: 38214.953 ms (00:38.215) [ec2-user@bastin ~]$ aws s3 ls s3://dataforrs/test20210405/ 2021-04-05 13:14:56 339563139 unloadtest_0000_part_00.gz 2021-04-05 13:14:56 339528727 unloadtest_0001_part_00.gz 2021-04-05 13:14:56 339460977 unloadtest_0002_part_00.gz 2021-04-05 13:14:56 339543307 unloadtest_0003_part_00.gz [ec2-user@bastin ~]$ パラレルモードオフ 明示的にparallel offを指定する 一つのファイルに書き込むためシリアルで処理する。MPPの利点を活かせないので当然パラレルモードと比べると遅い。 unload ('select * from unloadtest') to 's3://dataforrs/test20210406/unloadtest_' iam_role 'arn:aws:iam::xxxx:role/myRedshiftRole' header format csv gzip parallel off allowoverwrite; ログ mydb=# unload ('select * from unloadtest') mydb-# to 's3://dataforrs/test20210406/unloadtest_' mydb-# iam_role 'arn:aws:iam::xxxx:role/myRedshiftRole' mydb-# header mydb-# format csv mydb-# gzip mydb-# parallel off mydb-# allowoverwrite; INFO: UNLOAD completed, 87701667 record(s) unloaded successfully. UNLOAD Time: 151199.736 ms (02:31.200) mydb=# [ec2-user@bastin ~]$ aws s3 ls s3://dataforrs/test20210406/ 2021-04-05 13:19:18 1382206482 unloadtest_000.gz [ec2-user@bastin ~]$ 参考 データを Amazon S3 にアンロードする - Amazon Redshift https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/t_Unloading_tables.html --- ### PostgreSQL内の重複インデックスまたは未使用のインデックスを抽出 date: 2021-04-18 url: https://zatoima.github.io/postgresql-index-duplicate-unused-search.html tags: PostgreSQL 重複したインデックスの検索 SELECT indrelid::regclass AS TableName ,array_agg(indexrelid::regclass) AS Indexes FROM pg_index GROUP BY indrelid ,indkey HAVING COUNT(*) > 1; 未使用のインデックスの検索 WITH table_scans as ( SELECT relid, tables.idx_scan + tables.seq_scan as all_scans, ( tables.n_tup_ins + tables.n_tup_upd + tables.n_tup_del ) as writes, pg_relation_size(relid) as table_size FROM pg_stat_user_tables as tables ), all_writes as ( SELECT sum(writes) as total_writes FROM table_scans ), indexes as ( SELECT idx_stat.relid, idx_stat.indexrelid, idx_stat.schemaname, idx_stat.relname as tablename, idx_stat.indexrelname as indexname, idx_stat.idx_scan, pg_relation_size(idx_stat.indexrelid) as index_bytes, indexdef ~* 'USING btree' AS idx_is_btree FROM pg_stat_user_indexes as idx_stat JOIN pg_index USING (indexrelid) JOIN pg_indexes as indexes ON idx_stat.schemaname = indexes.schemaname AND idx_stat.relname = indexes.tablename AND idx_stat.indexrelname = indexes.indexname WHERE pg_index.indisunique = FALSE ), index_ratios AS ( SELECT schemaname, tablename, indexname, idx_scan, all_scans, round(( CASE WHEN all_scans = 0 THEN 0.0::NUMERIC ELSE idx_scan::NUMERIC/all_scans * 100 END),2) as index_scan_pct, writes, round((CASE WHEN writes = 0 THEN idx_scan::NUMERIC ELSE idx_scan::NUMERIC/writes END),2) as scans_per_write, pg_size_pretty(index_bytes) as index_size, pg_size_pretty(table_size) as table_size, idx_is_btree, index_bytes FROM indexes JOIN table_scans USING (relid) ), index_groups AS ( SELECT 'Never Used Indexes' as reason, *, 1 as grp FROM index_ratios WHERE idx_scan = 0 and idx_is_btree UNION ALL SELECT 'Low Scans, High Writes' as reason, *, 2 as grp FROM index_ratios WHERE scans_per_write <= 1 and index_scan_pct < 10 and idx_scan > 0 and writes > 100 and idx_is_btree UNION ALL SELECT 'Seldom Used Large Indexes' as reason, *, 3 as grp FROM index_ratios WHERE index_scan_pct < 5 and scans_per_write > 1 and idx_scan > 0 and idx_is_btree and index_bytes > 100000000 UNION ALL SELECT 'High-Write Large Non-Btree' as reason, index_ratios.*, 4 as grp FROM index_ratios, all_writes WHERE ( writes::NUMERIC / ( total_writes + 1 ) ) > 0.02 AND NOT idx_is_btree AND index_bytes > 100000000 ORDER BY grp, index_bytes DESC ) SELECT reason, schemaname, tablename, indexname, index_scan_pct, scans_per_write, index_size, table_size FROM index_groups; --- ### Oracle Enterprise EditionからStandard Editionへのダウングレード検討メモ date: 2021-04-15 url: https://zatoima.github.io/oracle-ee-se2-migration-to-aws-rds-for-oracle.html tags: Oracle, EE, SE2, RDS Enterprise EditionとStandard Editionで異なるところや移行する際に検討すべきことをメモ。以下、EnterPrise EditionはEE、Standard Edition2はSE2と略。MECEの視点も足りていないのでご注意ください。 SE2の概要 最大2ソケット データベースごとに16スレッドの実行に制限 移行元のシステムのCPU数に注意 EE限定の機能は使用できない 有償オプション製品のほぼ全て Oracle Advanced Security Oracle Real Application Testing Oracle Tuning Pack Oracle Diagnostics Pack Oracle Real Application Clusters (Oracle RAC) RACは18c以前まで無償で使用出来ていたが、19c以降はSE2では不可となった Oracle Partitioning Oracle Active Data Guard 他にも多数 EE特有の機能 Oracle Data Guard オンライン再編成 表領域のPoint-in-Timeリカバリ 各種パラレル処理 他にも多数 EEとSE2の使用出来る、使用できない機能の一覧 Exadata限定の機能とかOracle Cloudでのみ使用可能な機能があるので、左側のSE2とEEを確認。 Oracle Database Release 19 Databaseライセンス情報ユーザー・マニュアル https://docs.oracle.com/cd/F19136_01/dblic/Licensing-Information.html#GUID-B6113390-9586-46D7-9008-DCC9EDA45AB4 EEでもSE2でも変わらないこと 下記の通り、データベースとしての基本的な機能については変わらない。既存の資産(アプリケーション、ツール、スキル)は大部分は流用出来るはず。 トランザクション ストアド・プロシージャ RMAN ディクショナリビュー、静的ディクショナリ 注意すべきEE限定の機能について セキュリティ要件や可用性要件をどのように実現するかに関わってくるのでSE2化には第一ステップとしてアセスメントが必要。第二に性能。 個人的によく使われている or 使っていた or 素晴らしい機能をピックアップしてみた。他にもあるので、現在使用している機能を抽出した上で検討すべき。性能や可用性、セキュリティ要件の非機能要件だけではなく、既存運用にも大幅に影響が出てくるのでこれを一つ一つ大丈夫かどうか確認し、他の手段の検討含めてやっていく必要がある。 有償オプション Oracle Advanced Security(セキュリティ) Oracle Tuning Pack(チューニング関連) Oracle Diagnostics Pack(診断系) Oracle Real Application Clusters (可用性、性能) Oracle Partitioning(性能、運用面) Oracle Active Data Guard(可用性、性能) EE特有の機能 Basic Table Compression 各種パラレル処理 Data Guard オンライン系の操作(オンサイン索引再ビルド、オンライン再編成など) 表領域のPoint-in-Timeリカバリ パラレル・バックアップおよびリカバリ フラッシュバック操作 RMANバックアップから表や表パーティションを回復 結果キャッシュ 機能の代替をどうするか マネージドサービスであるRDS for Oracleを移行先として考える。ざっと気になったものを考えてみたが、一部はAWS特有の機能、もしくは機能が劣る代替機能(AWR→StatsPack)等に置き換えることで移行は可能。ただ、パーティション系やパラレル系や各種オプション製品が使えなくなることで非機能要件が満たせるかの確認が最初の検討の肝となる。 ※Oracleに対応した3rd Party製品は多くあるので、それと組み合わせるパターンも多く存在する。 カテゴリ EE SE2 AWS RDS for Oracle 備考 Security 表領域暗号化 - ストレージ暗号化で要件を満たすか確認 保護出来るレイヤーが違うことに注意 Security ネットワーク暗号化 ネットワーク暗号化 元々有償だったが、変わった模様 Performance 自動ワークロード・リポジトリ(AWR) Statspack Performance Insights、CloudWatch Performance ASH(Active Session History) - Performance Insights? Performance SQL Trace SQL Trace Performance Enterprise Manager の Performance周り - Performance Insights、CloudWatch Performance SQLアクセス・アドバイザ - Performance SQLチューニング・アドバイザ - Performance 自動SQLチューニング - Performance SQLプロファイル - Performance Oracle Partitioning ビューパーティション? - 要検討 Availability&Performance Oracle Real Application Clusters - Multi-AZ構成 Availability Data Guard - Multi-AZ構成 EE Feature オンライン系の操作 - EE Feature 表領域のPoint-in-Timeリカバリ - EE Feature パラレル・バックアップおよびリカバリ - スナップショット EE Feature フラッシュバック操作 - EE Feature RMANバックアップから表や表パーティションを回復 - EE Feature 結果キャッシュ - 補足 Partitionオプション無しでPartitionっぽくやる方法をやってみた Oracle Partiotionオプションの代替策(View+Trigger)を試してみる | my opinion is my own 👋 参考 EE Features in SE2 https://www.doag.org/formes/pubfiles/11343091/2019-NN-Clemens_Bleile-Oracle_Standard_Edition_2_Fehlende_Features_ergaenzen-Praesentation.pdf dbts19_cosol_oracle_se2.pdf http://cosol.jp/techdb/dbts19_cosol_oracle_se2.pdf --- ### EMR Pysparkでデータフレームを縦に連結してデータを増幅させる date: 2021-04-13 url: https://zatoima.github.io/aws-emr-spark-dataframe-data.html tags: AWS, EMR 手っ取り早くPysparkのデータフレームのデータを増やしたい場合に、データフレームを縦方向に結合することで増やそうと思った時に調べたメモ。S3上のCSVを読み込んだ後に、複数データフレームを一つのデータフレームに読み込んでいるだけ。 from pyspark.sql.types import * from functools import reduce from pyspark.sql import DataFrame schema = StructType([ StructField('file', StringType(), False), StructField('num', IntegerType(), False), StructField('row', IntegerType(), False), StructField('word', StringType(), False), StructField('subtype1', StringType(), False), StructField('subtype2', StringType(), False), StructField('subtype3', StringType(), False), StructField('subtype4', StringType(), False), StructField('conjtype', StringType(), False), StructField('conjugation', StringType(), False), StructField('basic', StringType(), False), StructField('ruby', StringType(), False), StructField('pronunce', StringType(), False) ]) df1 = spark.read.csv(f's3://xxxxx/aozora_data.csv', schema=schema, header=True) df2 = spark.read.csv(f's3://xxxxx/aozora_data.csv', schema=schema, header=True) df3 = spark.read.csv(f's3://xxxxx/aozora_data.csv', schema=schema, header=True) df4 = spark.read.csv(f's3://xxxxx/aozora_data.csv', schema=schema, header=True) df5 = spark.read.csv(f's3://xxxxx/aozora_data.csv', schema=schema, header=True) df6 = spark.read.csv(f's3://xxxxx/aozora_data.csv', schema=schema, header=True) df7 = spark.read.csv(f's3://xxxxx/aozora_data.csv', schema=schema, header=True) df8 = spark.read.csv(f's3://xxxxx/aozora_data.csv', schema=schema, header=True) df9 = spark.read.csv(f's3://xxxxx/aozora_data.csv', schema=schema, header=True) df10 = spark.read.csv(f's3://xxxxx/aozora_data.csv', schema=schema, header=True) df_union=reduce(DataFrame.unionByName, [df1, df2, df3, df4, df5, df6, df7, df8, df9, df10]) df_union.count() --- ### ublacklistでGoogle検索の結果をフィルタリングする date: 2021-04-12 url: https://zatoima.github.io/chrome-ublacklist-filter-url.html tags: その他, メモ Chromeの拡張機能であるublacklistを使用して検索結果から特定URLを含むサイトを除外することが出来る。 Chrome拡張機能 https://chrome.google.com/webstore/detail/ublacklist/pncfbmialoiaghdehhbnbhkkgmjanfhe/related?hl=ja 使い方 uBlacklistを使ってDevelopersIOを検索結果から除外する | DevelopersIO https://dev.classmethod.jp/articles/deny-devio-using-ublacklist/ リスト githubやgoogle driveのテキストを拡張機能から読み込めるらしいので、gistにアップロードしてみた。 https://raw.githubusercontent.com/zatoima/uBlacklist/main/ublacklist.txt *://code-examples.net/* *://codechacha.com/* *://codeday.me/* *://codezine.jp/* *://daviesmediadesign.com/* *://ja.coder.work/* *://ja.ojit.com/* *://ja.programqa.com/* *://ja.voidcc.com/* *://kotaeta.com/* *://living-sun.com/* *://matome.naver.jp/* *://my-best.com/* *://qastack.jp/* *://resonate.it/* *://riptutorial.com/* *://src-bin.com/* *://stackoverrun.com/* *://techacademy.jp/* *://tutorialmore.com/* *://webapps.stackovernet.com/* *://www.366service.com/* *://www.apowersoft.jp/* *://www.code-adviser.com/* *://www.codeflow.site/* *://www.dev4app.com/* *://www.hatsune.info/* *://www.matools.com/* *://www.sejuku.net/* *://www.soolide.com/* /.*it-swarm.*/ /.*pinterest.*/ /.*udemy.*/ --- ### ElastiCache(Redis)への定期書き込み用スクリプト date: 2021-04-07 url: https://zatoima.github.io/aws-elasticache-redis-bash-write-monitoring.html tags: AWS, ElastiCache, Redis, Bash ElastiCache Redisのフェイルオーバーやメンテナンス時にどのくらい影響があるかを調査する時に適当に準備したスクリプト タイムアウトを0.1秒に設定 接続不可の場合に、タイムアウトさせて次の処理に進むため redis-cliの戻り値で処理成功か否かでsleep時間を微調整 #!/bin/bash for a in {1..100000} do dt_now=`date "+%Y%m%d%H%M%S"` echo "===================" timeout -sKILL 0.1 redis-cli -c -h redis-test11.xxxxx.ng.0001.apne1.cache.amazonaws.com -p 6379 set $dt_now $a if [ $? != 0 ]; then # タイムアウトしたときの処理 echo "異常終了orタイムアウト" else # 正常終了したときの処理 echo "正常終了" sleep 1 fi echo $dt_now echo "===================" done --- ### RedshiftにTPC-DSデータをロードしてクエリ実行 date: 2021-04-03 url: https://zatoima.github.io/aws-redshift-tpcds-dataload.html tags: AWS, Redshift Redshiftのベンチマークにも使用されているTPCDSのデータロードと分析クエリの実行をやってみた。一定容量のデータ(100GBから1PBまで)が用意されていて、大容量データに対する分析用クエリを流したい時に簡易実行できる。 TPCDSベンチマークについてはこちら。小売製品サプライヤーの意思決定支援機能をモデル化している模様。 リソース確認 スクリプト系はamazon-redshift-utilsにまとまっている。 amazon-redshift-utils/src/CloudDataWarehouseBenchmark/Cloud-DWB-Derived-from-TPCDS at master · awslabs/amazon-redshift-utils · GitHub https://github.com/awslabs/amazon-redshift-utils/tree/master/src/CloudDataWarehouseBenchmark/Cloud-DWB-Derived-from-TPCDS データロード用のスクリプトは、US-EAST-1リージョンにあるので東京リージョンでRedshiftを実行する場合、転送オーバーヘッドには注意が必要かもしれない。 https://s3.console.aws.amazon.com/s3/buckets/redshift-downloads?prefix=TPC-DS%2F&region=us-east-1 手順概要 ddl.sqlを編集し、<USER_ACCESS_KEY_ID>と<USER_SECRET_ACCESS_KEY>を任意の有効なS3認証情報に置き換える。 データセットを読み込むための新しいデータベースを作成します 作成したデータベースに接続し、ddl.sqlを実行 ※データの規模やデータウェアハウスのサイズによっては、数時間かかる場合があるので注意 query_0.sql等を実行して実行時間を計測する 手順 ddl.sqlを編集 下記部分を自分のクレデンシャル情報に書き換える。対象のddl.sqlはこちら。git cloneなどでローカルに落として上で編集。 https://github.com/awslabs/amazon-redshift-utils/blob/master/src/CloudDataWarehouseBenchmark/Cloud-DWB-Derived-from-TPCDS/3TB/ddl.sql もちろんIAMロールを利用するように書き換えても大丈夫 copy call_center from 's3://redshift-downloads/TPC-DS/2.13/3TB/call_center/' iam_role 'arn:aws:iam::xxxxxxxxxxxxxxx:role/myRedshiftRole' gzip delimiter '|' EMPTYASNULL region 'us-east-1'; copy catalog_page from 's3://redshift-downloads/TPC-DS/2.13/3TB/catalog_page/' iam_role 'arn:aws:iam::xxxxxxxxxxxxxxx:role/myRedshiftRole' gzip delimiter '|' EMPTYASNULL region 'us-east-1'; copy catalog_returns from 's3://redshift-downloads/TPC-DS/2.13/3TB/catalog_returns/' iam_role 'arn:aws:iam::xxxxxxxxxxxxxxx:role/myRedshiftRole' gzip delimiter '|' EMPTYASNULL region 'us-east-1'; ~中略~ 2. データベースの作成 drop database tpcds_3tb; CREATE DATABASE tpcds_3tb; 3. 作成したデータベースに対してロードの実施 psql -h redshift-cluster.xxxxx.ap-northeast-1.redshift.amazonaws.com -U awsuser -d tpcds_3tb -p 5439 -f /home/ec2-user/amazon-redshift-utils-master/src/CloudDataWarehouseBenchmark/Cloud-DWB-Derived-from-TPCDS/3TB/ddl.sql テーブル作成、データロード、件数確認が実行される。(時間が掛かるので注意) 4. queryを実行 query_0.sql ~ query_10.sqlまで用意されているので、適宜実行。ベンチマークする際にはリザルトキャッシュの無効化なども忘れずに。 psql -h redshift-cluster.xxxxx.ap-northeast-1.redshift.amazonaws.com -U awsuser -d tpcds_3tb -p 5439 -f /home/ec2-user/amazon-redshift-utils-master/src/CloudDataWarehouseBenchmark/Cloud-DWB-Derived-from-TPCDS/3TB/queries/query_0.sql --- ### Redshiftへのデータロード date: 2021-04-01 url: https://zatoima.github.io/aws-redshift-dataload-from-s3.html tags: AWS, Redshift IAMロールと必要なIAMロールのクラスタへのアタッチ等は完了済という想定。 ロード用のファイルをS3にアップロードする aws s3 cp aozora_data.csv s3://xxxx/load/ ロード用のファイルは約6G、約1億件弱。(青空文庫のテキストデータ) [ec2-user@bastin ~]$ ls -lh aozora_data.csv -rw-rw-r-- 1 ec2-user ec2-user 6.1G Dec 16 2012 aozora_data.csv [ec2-user@bastin ~]$ wc -l aozora_data.csv 87701673 aozora_data.csv Redshiftにロード先のテーブルを用意 CREATE TABLE aozora_data(file VARCHAR(100),num INT,row INT,word TEXT,subtype1 VARCHAR(100),subtype2 VARCHAR(100),subtype3 VARCHAR(100),subtype4 VARCHAR(100),conjtype VARCHAR(30),conjugation VARCHAR(30),basic TEXT,ruby TEXT,pronunce TEXT ); データロード実行 copy aozorabunko_data from 's3://xxxxx/load/aozora_data.csv' iam_role 'arn:aws:iam::xxxxx:role/myRedshiftRole' csv; 上記の方法はアンチパターンであり、一つのスライスでしか実行されず、MPPアーキテクチャのRedshiftではリソースを有効活用出来ない。下記のベスト・プラクティスにある通り、ファイル分割、ファイル圧縮を実施した上での実行が望ましい。 Amazon Redshift データのロードのベストプラクティス - Amazon Redshift https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/c_loading-data-best-practices.html データ分割 split -n 8 -d aozora_data.csv part- --- ### pythonのpyautoguiを使用した画像認識処理待ちメモ date: 2021-02-28 url: https://zatoima.github.io/python-pyautogui-waiting-memo.html tags: python 画像認識をpyautoguiで実行させる場合で、どのように処理待ちをするかというメモ。当初は一定期間sleepさせる原始的な方法にしていたが、該当の画像がどのくらいで表示されるかが不明な場合、余裕を持ってsleepさせる必要があり、結果的に多くの時間が掛かっていた。 time.sleep(15) pos_check=pyautogui.locateOnScreen('対象の画像のパス', confidence=0.6) pyautogui.click(pos_check) 該当の画像が表示されるまで、ループを回しながらsleepさせるようにした。画像が見当たらない場合は、ImageNotFoundExceptionが発生するので、そちらでスリープしてcontinueするように調整。 import pyscreeze from pyscreeze import ImageNotFoundException ~中略~ def click_from_imagename(imagename,confidence,message): for tryCount in range(30): #該当の画像が画面上に存在する場合の処理 try: if pyautogui.locateOnScreen(imagename, confidence=confidence): print('Execute:{0}'.format(message)) pos_check=pyautogui.locateOnScreen(imagename, confidence=confidence) pyautogui.click(pos_check) time.sleep(1) print('Done:{0}'.format(message)) break #該当の画像が画面上に存在しない場合の処理 except pyautogui.ImageNotFoundException: print('Waiting:{0}'.format(message)) time.sleep(1) continue ~中略~ 呼び出し時 click_from_imagename("対象の画像のパス",0.6,"実行名") --- ### モンテカルロ法で全世界株式への20年後の投資リターンの推測 date: 2021-02-22 url: https://zatoima.github.io/asset-montecarlo-forecast.html tags: 資産運用, その他 モンテカルロ法はランダム試行をサンプル回数ほど繰り返すことで解に近い値に収束するという結果を導くもので、乱数によりリターンとリスクに従った正規分布を作る。Excelの関数だと下記となる。 NORM.INV(RAND(),リターン(平均),リスク(標準偏差)) 分散投資の代名詞である全世界株式インデックスのベンチマークで使われるACWIの20年の年率平均リターンは6.7%で年率平均リスク(標準偏差)は15.9%となり、この2つの変数を使ってシミュレーションをしてみる。 6か月 1年 3年 5年 10年 15年 20年 30年 リターン (%) 24.3 16.8 10.6 12.9 9.7 7.8 6.7 8.4 リスク (%) 14.3 26 18.4 15.1 14.1 16.3 15.9 15 『MSCI オール・カントリー・ワールド・インデックス (ACWI)』 |株価指数 https://myindex.jp/data_i.php?q=MS1025USD 上記のリターンとリスクを元に、100万円スタート(追加の積立資金は無し)で50,000回ほどモンテカルロ法でシミュレーションを実施して最終的に出力された結果がこちら。計算用のExcelシートはこちら。20MB前後あるので注意。 5万回ほどのサンプルケースをごにょごにょして下記の数値を計算してグラフ化している。再計算のたびに少し値はズレるが大体の傾向は変わらない。 期待リターン 中央値 平均値 上位xx% 上位xx%という表現がわかりにくさを招いているが、ワースト10%(=上位90%)の場合でも元本からは多少増えており、中央値は複利の効果で約3倍という結果になった。 --- ### Windows版 Kindleの自動スクリーンショットツール date: 2021-02-15 url: https://zatoima.github.io/python-kindle-screenshot-get.html tags: Python, その他, メモ このスクリーンショットは自分用に実施しましょう。 参考サイト こちらのソースをベースに使いやすいように修正。 【Python】pyautoguiを使ってKindle書籍を自動でスクショするツールを作ってみた! | 都会のエレキベア https://elekibear.com/20200225_01 キャプチャする座標の取得 パソコンごとに座標は異なってくるので座標を取得する import pyautogui import time # 左上座標を取得 print('3秒以内にキャプチャ範囲の左上座標にマウスカーソルを合わせてください') time.sleep(3) print('左上座標:' + str(pyautogui.position())) # 1秒待機 time.sleep(1) # 右下座標を取得 print('3秒以内にキャプチャ範囲の右下座標にマウスカーソルを合わせてください') time.sleep(3) print('右下座標:' + str(pyautogui.position())) Kindleのキャプチャ取得 import pyautogui import time import os import datetime # ページ数 page = 600 #←変更必要 # スクショ間隔(秒) span = 0.1 # 出力フォルダ頭文字 h_foldername = "output" # 出力ファイル頭文字 h_filename = "picture" # 取得範囲:左上座標 x1, y1 = 825, 105 #"キャプチャする座標の取得"を元に修正する # 取得範囲:右下座様 x2, y2 = 1781, 989 #"キャプチャする座標の取得"を元に修正する #5秒の間に、スクショしたいkindleの画面に移動 time.sleep(5) # 出力フォルダ作成(フォルダ名:頭文字_年月日時分秒) folder_name = h_foldername + "_" + str(datetime.datetime.now().strftime("%Y%m%d%H%M%S")) os.mkdir(folder_name) # スクショ処理 for p in range(page): # 出力ファイル名(頭文字_連番.png) out_filename = h_filename + "_" + str(p+1).zfill(4) + '.png' # 画面全体のスクリーンショット s = pyautogui.screenshot(region=(x1, y1, x2-x1, y2-y1)) # 出力パス: 出力フォルダ名 / 出力ファイル名 s.save(folder_name + "/" + out_filename) # 次のページ pyautogui.keyDown('right') pyautogui.keyUp('right') # 画面の動作待ち time.sleep(span) --- ### Oracle 19cで拡張VARCHAR2型を導入 date: 2021-02-12 url: https://zatoima.github.io/oracle-19c-extended-varchar2.html tags: Oracle コマンド DBをupgradeモードとする。 shutdown immediate startup upgrade select status from v$instance; 初期化パラメータの変更 ALTER SYSTEM SET max_string_size=extended SCOPE=SPFILE; utl32k.sqlの実行 @?/rdbms/admin/utl32k.sql マルチテナント環境なので、PDB$SEEDにも実行 alter session set container=PDB$SEED; @?/rdbms/admin/utl32k.sql DB停止、起動 shutdown immediate startup show parameters max_string_size ログ SQL> shutdown immediate データベースがクローズされました。 データベースがディスマウントされました。 ORACLEインスタンスがシャットダウンされました。 SQL> startup upgrade ORACLEインスタンスが起動しました。 Total System Global Area 2415918568 bytes Fixed Size 9137640 bytes Variable Size 754974720 bytes Database Buffers 1644167168 bytes Redo Buffers 7639040 bytes データベースがマウントされました。 データベースがオープンされました。 SQL> select status from v$instance; STATUS ------------------------------------ OPEN MIGRATE SQL> show con_name CON_NAME ------------------------------ CDB$ROOT SQL> ALTER SYSTEM SET max_string_size=extended SCOPE=SPFILE; システムが変更されました。 SQL> @?/rdbms/admin/utl32k.sql セッションが変更されました。 セッションが変更されました。 DOC>####################################################################### DOC>####################################################################### DOC> The following statement will cause an "ORA-01722: invalid number" DOC> error if the database has not been opened for UPGRADE. DOC> DOC> Perform a "SHUTDOWN ABORT" and DOC> restart using UPGRADE. DOC>####################################################################### DOC>####################################################################### DOC># レコードが選択されませんでした。 DOC>####################################################################### DOC>####################################################################### DOC> The following statement will cause an "ORA-01722: invalid number" DOC> error if the database does not have compatible >= 12.0.0 DOC> DOC> Set compatible >= 12.0.0 and retry. DOC>####################################################################### DOC>####################################################################### DOC># PL/SQLプロシージャが正常に完了しました。 セッションが変更されました。 0行が更新されました。 コミットが完了しました。 システムが変更されました。 PL/SQLプロシージャが正常に完了しました。 コミットが完了しました。 システムが変更されました。 セッションが変更されました。 セッションが変更されました。 表が作成されました。 表が作成されました。 表が作成されました。 表が切り捨てられました。 0行が作成されました。 PL/SQLプロシージャが正常に完了しました。 STARTTIME -------------------------------------------------------------------------------- 02/10/2021 14:52:52.619389000 PL/SQLプロシージャが正常に完了しました。 エラーはありません。 PL/SQLプロシージャが正常に完了しました。 セッションが変更されました。 セッションが変更されました。 0行が作成されました。 レコードが選択されませんでした。 レコードが選択されませんでした。 DOC>####################################################################### DOC>####################################################################### DOC> The following statement will cause an "ORA-01722: invalid number" DOC> error if we encountered an error while modifying a column to DOC> account for data type length change as a result of enabling or DOC> disabling 32k types. DOC> DOC> Contact Oracle support for assistance. DOC>####################################################################### DOC>####################################################################### DOC># PL/SQLプロシージャが正常に完了しました。 PL/SQLプロシージャが正常に完了しました。 コミットが完了しました。 パッケージが変更されました。 パッケージが変更されました。 セッションが変更されました。 SQL> alter session set container=PDB$SEED; セッションが変更されました。 SQL> SQL> @?/rdbms/admin/utl32k.sql セッションが変更されました。 ~中略~ SQL> shutdown immediate データベースがクローズされました。 データベースがディスマウントされました。 ORACLEインスタンスがシャットダウンされました。 SQL> SQL> SQL> SQL> SQL> startup ORACLEインスタンスが起動しました。 Total System Global Area 2415918568 bytes Fixed Size 9137640 bytes Variable Size 754974720 bytes Database Buffers 1644167168 bytes Redo Buffers 7639040 bytes データベースがマウントされました。 データベースがオープンされました。 SQL> SQL> show parameters max_string_size NAME TYPE ------------------------------------ --------------------------------- VALUE ------------------------------ max_string_size string EXTENDED SQL> --- ### Aurora PostgreSQLのフェイルオーバー時間の計測 date: 2021-02-10 url: https://zatoima.github.io/aws-aurora-failover-time-test/ tags: AWS, Aurora, RDS, PostgreSQL はじめに Auroraのよくある質問を見ていたらフェイルオーバーが30秒以内に完了するとあったので、一応確認してみた。 https://aws.amazon.com/jp/rds/aurora/faqs/ Q: フェイルオーバー中はどのようなことが起き、どのくらいの時間がかかりますか? フェイルオーバーは Amazon Aurora によって自動的に処理されるため、アプリケーションは管理上の手動介入なしで、可能な限り迅速にデータベースオペレーションを再開することができます。 Amazon Aurora レプリカを同一の、または異なるアベイラビリティーゾーンに作成しておくと、フェイルオーバーが発生した場合、Aurora は DB インスタンスの正規名レコード (CNAME) を切り替えて正常なレプリカを指定します。指定されたレプリカはこれにより新しいプライマリに昇格します。フェイルオーバーは開始から終了まで通常 30 秒以内に完了します。 事前準備 テスト用のテーブル作成 create table failovertest(id serial,time timestamp); 雑なテスト用スクリプト。接続エラーが発生しても継続するようにexceptでpass。 import psycopg2 import psycopg2.extras import time import datetime for i in range(20000): try: dt_now = datetime.datetime.now() conn = psycopg2.connect("host=xxxxxx.cluster-xxxxx.ap-northeast-1.rds.amazonaws.com port=5432 dbname=xxx user=xxx password=xx") cur = conn.cursor() cur.execute("insert into failovertest (time) values (current_timestamp)") print(dt_now) time.sleep(1) conn.commit() cur.close() conn.close() except: pass 結果 平均12秒という結果に。 Start End 秒数 1回目 2:20:40 2:20:53 0:00:13 2回目 2:23:19 2:23:30 0:00:11 3回目 2:24:37 2:24:53 0:00:16 4回目 11:29:03 11:29:13 0:00:10 5回目 11:30:06 11:30:18 0:00:12 --- ### Aurora PostgreSQLとRDSの比較メモ(リンク集) date: 2021-02-07 url: https://zatoima.github.io/aws-aurora-rds-postgresql-compare-link.html tags: AWS, Aurora, RDS, PostgreSQL ① AuroraかRDSどちらを選ぶべきか比較する話をDevelopers.IO 2019 in OSAKAでしました #cmdevio | Developers.IO https://dev.classmethod.jp/articles/developers-io-2019-in-osaka-aurora-or-rds/ ② AWS re:Invent 2019 - DAT328 Deep Dive on Amazon Aurora PostgreSQL https://www.slideshare.net/GrantMcAlister/aws-reinvent-2019-dat328-deep-dive-on-amazon-aurora-postgresql [レポート] PostgreSQL互換のRDSとAuroraの違いが分かるセッション DAT328 Deep dive on Amazon Aurora with PostgreSQL compatibility #reinvent | Developers.IO https://dev.classmethod.jp/articles/reinvent-2019-dat328-r/ ③ 2019年度WG3活動成果報告 クラウド検証編 https://pgecons-sec-tech.github.io/tech-report/pdf/wg3_2019_AWS_1.pdf ④ 2019年度WG3活動成果報告 クラウド検証編 ②実機検証編(AWS) https://pgecons-sec-tech.github.io/tech-report/pdf/wg3_2019_AWS_2.pdf --- ### Oracle Exadataの代表的な機能 date: 2021-02-02 url: https://zatoima.github.io/oracle-exadata-typical-functions.html tags: Oracle, Exadata Exadataの代表的な機能(性能面) Oracle Exadata System Softwareの概要 https://docs.oracle.com/cd/F19137_01/sagug/exadata-storage-server-software-introduction.html#GUID-D6856B9A-DBB2-44DF-8632-01637AFAE962 性能分析時に必要な統計値など SmartScanを始めとした効果を分析する際はこちらの統計を参照するのが良さそう。Oracle製品の良いところは機能面もそうだが、調べると情報が出てきやすいところ。 津島博士のパフォーマンス講座 第69回 Oracle Exadata Database Machineについて | Oracle Technology Network Japan Blog https://blogs.oracle.com/otnjp/tsushima-hakushi-69 統計名 意味 V$SQLの統計 cell physical IO interconnect bytes DBサーバーとCellの間でやりとりされたIOサイズで、Smart Scan以外も含む(解凍後のサイズ) IO_INTERCONNECT_BYTES cell physical IO interconnect bytes returned by smart scan Smart ScanによりCellから返されたIOサイズ(解凍後のサイズ) IO_CELL_OFFLOAD_RETURNED_BYTES cell physical IO bytes eligible for predicate offload Smart Scanの対象となったIOサイズ(physical read total bytesとの違いはSmart Scan以外が含まない) IO_CELL_OFFLOAD_ELIGIBLE_BYTES cell IO uncompressed bytes cellで処理された非圧縮のデータ・サイズ IO_CELL_UNCOMPRESSED_BYTES cell physical IO bytes saved by storage index Storage indexによるIO削減サイズ OPTIMIZED_PHY_READ_REQUESTS cell flash cache read hits Smart Flash Cacheに対するリクエスト回数 physical read total IO requests 物理読込みI/Oリクエスト回数 PHYSICAL_READ_REQUESTS physical read total Bytes 物理読込みサイズ(バイト) PHYSICAL_READ_BYTES その他参考 Exadataフラッシュキャッシュの謎:オラクルデータベースの技術メモ:So-netブログ https://tech-oracle.blog.ss-blog.jp/2019-02-06 --- ### IIJmioの携帯電話から他番号へ転送設定を行う date: 2021-02-01 url: https://zatoima.github.io/iijmio-telephone-transfer.html tags: その他, メモ IIJmioでは転送でんわサービスを利用出来る。利用したいシチュエーションがあったのでメモ。 参考 https://www.iijmio.jp/hdd/miofone/voiceopt.html#transfer 注意点 契約の携帯電話から転送先への通話料が、転送でんわサービスの契約者に掛かる。 発信元の料金も必要となる。 転送設定を行った段階で、留守番電話が無効となる。 転送時間までの秒数を指定出来る(デフォルト7秒) 転送設定を行った後の状態だと、「この電話を転送しますので、少々お待ちください」というアナウンスが流れる ガイダンス設定を必要に応じて変更する 手順 転送時間を5秒に変更し、ガイダンスを無しに設定する場合、下記手順が必要となる。 https://www.iijmio.jp/hdd/miofone/voiceopt.html#transfer 転送先電話番号の登録・変更 転送でんわサービスの開始 ガイダンスを無しに設定 呼び出し時間を「5秒」に設定 --- ### 『AWS 認定 DevOps エンジニア – プロフェッショナル』合格に向けて date: 2021-01-30 url: https://zatoima.github.io/aws-certified-devops-professional.html tags: AWS 約1ヶ月の勉強でAWS 認定 DevOps エンジニア – プロフェッショナルを合格することが出来たので簡単にメモ。 準備方法 試験ガイド 重要サービスのBlackBelt資料 公式の無料対策E-Learning Exam Readiness: AWS Certified DevOps Engineer – Professional 実機検証(特にCF、Codeシリーズあたり) 公式模擬試験 有料問題集(Whizlabs) ホワイトペーパー AWS における継続的インテグレーションと継続的デリバリーの実践 勉強対象 Solution Architect Professionalや各種Specialityの勉強で幅広く勉強していたので、重要サービスだけ重点的に実機触ったり勉強したりした。スムーズに勉強が進んだのは既にSAP等を取得しているのも大きいと思う。 重要なサービス Systems Manager CloudFormation Elastic Beanstalk Config CodePipeline/CodeBuild/CodeDeploy CloudWatch(特にLogs、Events等) AutoScaling ECS 必要な概念 CICD 災対設計 デプロイメント(ブルーグリーン/カナリアリリースなど) これがわかりやすい 【AWS Black Belt Online Seminar】Deployment on AWS RTO/RPOの概念 ユースケースごとにバックアップや設計が異なるので適切なケースを選択できるか バックアップ/リカバリ できればざっくり勉強した方が良いサービス Inspector EC2 Opsworks StepFunction GuardDuty Macie KMS DynamoDB 所感・その他 CICDを始めとしたDevOpsで必要な概念、運用時に必要な知識、スキルが身についた気がする。問題のケースが実務で検討していたシチュエーションと酷似しており、普段の仕事でも生かせそうと試験中に思った。 無事に合格して11冠に。ここまで来ると12冠が最終目標だが、機械学習の知識定着に向けたG検定やIPA試験に向けて冬・春は勉強予定。 https://www.youracclaim.com/users/jumpei-imazato/badges AWS Certified Cloud Practitioner AWS Certified Solutions Architect – Associate AWS Certified Developer – Associate AWS Certified SysOps Administrator – Associate AWS Certified Solutions Architect – Professional AWS Certified DevOps Engineer – Professional AWS Certified Security – Specialty AWS Certified Machine Learning – Specialty AWS Certified Database – Specialty AWS Certified Data Analytics – Specialty AWS Certified Alexa Skill Builder – Specialty --- ### AWS Elastic Beanstalkの殴り書きメモ date: 2021-01-28 url: https://zatoima.github.io/aws-elastic-beanstalk-memo.html tags: AWS, Elastic Beanstalk はじめに ついつい、「ElasticBeanStalk」とか「Elastic Bean Stalk」とか書きがちなのでまずはそこから。 殴り書きメモ 定番構成の構築・アプリデプロイの自動化サービス 構成要素 アプリケーション トップレベルの論理単位 バージョン、環境、環境設定が含まれる バージョン デプロイ可能なコード S3上でのバージョン管理 異なる環境に異なるバージョンをデプロイ可能 環境 各環境に応じて構築されるインフラ環境 バージョン(ソースコード)をデプロイ 例:Webサーバ環境:ELB+EC2(コードがデプロイされる) 環境設定 環境に関連するリソースの動作を定義する設定パラメータ 例:EC2のインスタンスタイプ、Auto Scalingの設定等 環境のタイプ ロードバランシング環境、Auto Scaling環境 スケーラブルなウェブアプリケーションを実行 高い可用性と伸縮自在性を兼ね備えた構成 Webサーバ環境:ELB+Auto Scaling ワーカー環境:SQS+Auto Scaling シングルインスタンス環境 バッチアプリケーションの実行環境として EC2 1台構成(Auto Scaling Max1台、Min1台) EB CLI インストール [ec2-user@bastin ~]$ sudo pip3 install --upgrade awsebcli WARNING: pip is being invoked by an old script wrapper. This will fail in a future version of pip. Please see https://github.com/pypa/pip/issues/5599 for advice on fixing the underlying issue. To avoid this problem you can invoke Python with '-m pip' instead of running pip directly. Collecting awsebcli Downloading awsebcli-3.19.2.tar.gz (249 kB) |████████████████████████████████| 249 kB 14.3 MB/s Collecting botocore<1.20.0,>=1.19.0 サンプルコードのダウンロード [ec2-user@bastin ~]$ git clone https://github.com/aws-samples/eb-node-express-sample.git Cloning into 'eb-node-express-sample'... remote: Enumerating objects: 8, done. remote: Counting objects: 100% (8/8), done. remote: Compressing objects: 100% (7/7), done. remote: Total 111 (delta 0), reused 2 (delta 0), pack-reused 103 Receiving objects: 100% (111/111), 269.62 KiB | 496.00 KiB/s, done. Resolving deltas: 100% (34/34), done. Elastic Beanstalkアプリケーションの作成 [ec2-user@bastin eb-node-express-sample]$ eb init Select a default region 1) us-east-1 : US East (N. Virginia) 2) us-west-1 : US West (N. California) 3) us-west-2 : US West (Oregon) 4) eu-west-1 : EU (Ireland) 5) eu-central-1 : EU (Frankfurt) 6) ap-south-1 : Asia Pacific (Mumbai) 7) ap-southeast-1 : Asia Pacific (Singapore) 8) ap-southeast-2 : Asia Pacific (Sydney) 9) ap-northeast-1 : Asia Pacific (Tokyo) 10) ap-northeast-2 : Asia Pacific (Seoul) 11) sa-east-1 : South America (Sao Paulo) 12) cn-north-1 : China (Beijing) 13) cn-northwest-1 : China (Ningxia) 14) us-east-2 : US East (Ohio) 15) ca-central-1 : Canada (Central) 16) eu-west-2 : EU (London) 17) eu-west-3 : EU (Paris) 18) eu-north-1 : EU (Stockholm) 19) eu-south-1 : EU (Milano) 20) ap-east-1 : Asia Pacific (Hong Kong) 21) me-south-1 : Middle East (Bahrain) 22) af-south-1 : Africa (Cape Town) (default is 3): 9 Select an application to use 1) bel-dev-beanstalk-test 2) [ Create new Application ] (default is 2): Enter Application Name (default is "eb-node-express-sample"): Application eb-node-express-sample has been created. It appears you are using Node.js. Is this correct? (Y/n): y Select a platform branch. 1) Node.js 12 running on 64bit Amazon Linux 2 2) Node.js 10 running on 64bit Amazon Linux 2 3) Node.js running on 64bit Amazon Linux (default is 1): Do you wish to continue with CodeCommit? (Y/n): n Do you want to set up SSH for your instances? (Y/n): y Select a keypair. 1) awskeypair 2) DMSHandson58 3) [ Create new KeyPair ] (default is 2): 1 [ec2-user@bastin eb-node-express-sample]$ 環境作成、コードのデプロイ [ec2-user@bastin eb-node-express-sample]$ eb create Enter Environment Name (default is eb-node-express-sample-dev): Enter DNS CNAME prefix (default is eb-node-express-sample-dev): Select a load balancer type 1) classic 2) application 3) network (default is 2): Would you like to enable Spot Fleet requests for this environment? (y/N): N ~省略~ デプロイメント デプロイポリシーと設定 - AWS Elastic Beanstalk https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/using-features.rolling-version-deploy.html In Place Deployment(Rolling Deploy) インスタンスは現行環境のものを利用して、新しいリビジョンのコードを反映 at once Rolling Blue/Green Deployment 新しいリビジョンのコードを新しいインスタンスに反映させ、インスタンスごと入れ替える デプロイ設定 バッチタイプ:一度にデプロイを反映させる台数 割合、固定 バッチサイズ:各バッチにデプロイするインスタンスの数、または割合 URL Swap あるバージョンのアプリケーションをデプロイ後、新しいバージョンのアプリケーションを違う環境(Environment)としてデプロイ。CNAMEを切り替えて、Blue/Green Deploymentを実現する Elastic BeanstalkのCNAME Swapを試してみる | Developers.IO https://dev.classmethod.jp/articles/beanstalk-cname-swap/ Route53の加重ラウンドロビン 新バージョンのコードを少しずつ試すことが可能 環境設定のカスタマイズ 環境作成時にオプションを直接指定 保存済み設定 S3に設定ファイルとして保存 eb config save .ebextensions リソースのカスタマイズが可能 カスタム環境変数 ソフトウェアインストール ソフトウェアの実行 デフォルトにはないAWSリソースの作成 モニタリング 基本ヘルスレポート 環境のヘルスステータス ELBのヘルスチェック CloudWatchメトリクス 拡張ヘルスレポート OSレベルのメトリクス アプリケーションレベルのメトリクス ​ --- ### PostgreSQLでNOLOGGINGテーブル(UNLOGGED)に大量データをロード date: 2021-01-27 url: https://zatoima.github.io/aws-aurora-rds-postgresql-nologging-load.html tags: AWS, Aurora, RDS, PostgreSQL UNLOGGEDテーブルとは UNLOGGEDテーブルはOracle Databaseで言うところのUNLOGGINGテーブルでWALに書き出さないテーブルとなり、高速化が見込める。一方、クラッシュ時には当然WALにデータがないので、リカバリが出来ない。 とは言え、データロード等のリトライ可能な処理には有効なので、効果含めて確認してみる 設定方法 テーブル作成時にオプションを付けるかALTER TABLE文を使用するか。今回はALTER TABLEで実施してみる ALTER TABLE aozora SET UNLOGGED; ALTER TABLE aozora SET LOGGED; CREATE TABLE https://www.postgresql.jp/document/12/html/sql-createtable.html ALTER TABLE https://www.postgresql.jp/document/12/html/sql-altertable.html テーブル作成 青空文庫のテキストデータをロード出来るようにテーブルを準備 CREATE TABLE aozora(file VARCHAR(30),num INT,row INT,word TEXT,subtype1 VARCHAR(30),subtype2 VARCHAR(30),subtype3 VARCHAR(30),subtype4 VARCHAR(10),conjtype VARCHAR(15),conjugation VARCHAR(15),basic TEXT,ruby TEXT,pronunce TEXT ); ALTER TABLE aozora SET UNLOGGED; 作成後にテーブル定義を確認するとUnlogged table "public.aozora"と表示されるようになっている。 postgres=> \d aozora Unlogged table "public.aozora" Column | Type | Collation | Nullable | Default -------------+-----------------------+-----------+----------+--------- file | character varying(30) | | | num | integer | | | row | integer | | | word | text | | | subtype1 | character varying(30) | | | subtype2 | character varying(30) | | | subtype3 | character varying(30) | | | subtype4 | character varying(10) | | | conjtype | character varying(15) | | | conjugation | character varying(15) | | | basic | text | | | ruby | text | | | pronunce | text | | | 結果 約3割ほどUNLOGGEDテーブルの方が早い結果に。 テーブル種別 時間 UNLOGGEDテーブル 0:04:41 LOGGEDテーブル 0:06:11 UNLOGGEDテーブルの場合 [ec2-user@bastin ~]$ time psql -h aurorav1.cluster-xxxxx.ap-northeast-1.rds.amazonaws.com -d postgres -U postgres -c "COPY aozora(file,num,row,word,subtype1,subtype2,subtype3,subtype4,conjtype,conjugation,basic,ruby,pronunce) from stdin with csv DELIMITER ','" < /home/ec2-user/utf8_all.csv COPY 87701673 real 4m41.921s user 0m19.347s sys 0m6.618s LOGGEDテーブルの場合 [ec2-user@bastin ~]$ time psql -h aurorav1.cluster-xxxxxx.ap-northeast-1.rds.amazonaws.com -d postgres -U postgres -c "COPY aozora(file,num,row,word,subtype1,subtype2,subtype3,subtype4,conjtype,conjugation,basic,ruby,pronunce) from stdin with csv DELIMITER ','" < /home/ec2-user/utf8_all.csv COPY 87701673 real 6m11.123s user 0m18.744s sys 0m6.738s --- ### AWS Systems Managerの殴り書きメモ date: 2021-01-24 url: https://zatoima.github.io/aws-systems-manager-memo-for-devops-pro.html tags: AWS, Systems Manager はじめに 「AWS 認定 DevOps エンジニア – プロフェッショナル」に向けた勉強メモ 殴り書きメモ AWS Systems Manager はじめに マネージドインスタンス化 SSM Agentの導入 SSM Agent側(EC2)からSSMへのアクセス権が必要 インターネット経由 or VPCエンドポイント経由 EC2ロール - クイックセットアップ SSMの各機能 AWS SSM Explorer Gyazo AWSリソースに関する情報をレポートするオペレーションダッシュボード EC2情報 EC2インスタンス数 マネージドインスタンス数などなど OpsCenter OpsItems パッチコンプライアンス Trusted Advisorのチェック SSM OpsCenter AWSリソースに関連する運用作業項目を表示、調査、解決できるダッシュボード CloudWatch Eventsのルールを登録 外部アラートも登録可能 SSMコンプライアンス コンプライアンスに準拠していないリソースを表示可能 デフォルト パッチ適用状況 ステートマネージャーの関連付け状況 SSMインベントリ マネージドインスタンスからメタデータを収集し可視化 OS上のアプリケーション一覧 Configに構成情報を送信してインベントリ情報の変更追跡が可能 Config Rulesで準拠状況をチェック Gyazo SSMドキュメント 運用処理をSSMドキュメントにて定義して実行する Gyazo 汎用的な処理はAWS側で事前に定義 作成したドキュメントは"run command"等で実行 SSMステートマネージャー 定義された状態に保つプロセスを自動化 サーバの状態を確認、是正するための定期的な処理に向く サーバ郡に対して定期的に処理を行うためのフレームワーク 例:インベントリ収集、SSMAgentの定期更新 SSMメンテナンスウィンドウ アクションを実行するスケジュールを定義 サービス停止を伴うような重い処理向け OSパッチ適用、バックアップ取得 SSMパッチマネージャー マネージドインスタンスにパッチを適用するプロセスを自動化 パッチルール準拠の確認 Scan Scan&Install セッションマネージャー 通信ポートを開放せずにサーバへのシェルアクセスが可能 インスタンスをセキュアに プライベートサブネットのインスタンスにもアクセスできるので、踏み台いらず。 アクセス制御はIAMユーザのIAM Policy 操作ログをCloudWatch logs or S3に保存可能 接続履歴はCloudTrail SSMパラメータストア 構成や設定情報の管理のためのストレージ パスワードの機密情報をKMSで暗号化 --- ### AuroraとNeptuneのメンテナンス(パッチ適用)について date: 2021-01-22 url: https://zatoima.github.io/aws-aurora-neptune-maintenance-about.html tags: AWS, Aurora, Neptune はじめに RDSのメンテナンスの種類は「Available(利用可能) 」と「Required(必須) 」の種類が存在する。Aurora(PostgreSQL)とNeptuneにそれぞれAvailableとRequiredのパッチがあったので確認してみる。 NeptuneはRDSのと運用周りは同じな模様。(全てが一緒というわけではないと思うが。) https://docs.aws.amazon.com/ja_jp/neptune/latest/userguide/limits.html > 特定の管理機能のために、Amazon Neptune は Amazon Relational Database Service (Amazon RDS) と共有の運用テクノロジーを使用します。 Neptune Aurora Available(利用可能) とRequired(必須) について 必須 – メンテナンスアクションがリソースに適用され、延期はできません。 利用可能 – メンテナンスアクションは利用可能ですが、自動的にはリソースに適用されません。手動で適用できます。 DescribePendingMaintenanceActions API メンテナンスについてはDescribePendingMaintenanceActions APIから確認することが出来る。 [ec2-user@bastin ~]$ aws rds describe-pending-maintenance-actions { "PendingMaintenanceActions": [ { "PendingMaintenanceActionDetails": [ { "Action": "system-update", "Description": "Upgrade to Aurora PostgreSQL 3.1.2" } ], "ResourceIdentifier": "arn:aws:rds:ap-northeast-1:xxxxxx:cluster:xxxxxxxpostgresv11" }, { "PendingMaintenanceActionDetails": [ { "Action": "system-update", "CurrentApplyDate": "2020-05-08T18:33:00Z", "AutoAppliedAfterDate": "2020-05-08T18:33:00Z", "Description": "Engine Patch Upgrade" } ], "ResourceIdentifier": "arn:aws:rds:ap-northeast-1:xxxxxxx:cluster:xxxxxxx-cluster" } ] } CLIの場合はAvailable(利用可能)かRequired(必須) かどうかは項目を見るだけではわからない。Required(必須)の場合はAutoAppliedAfterDate、CurrentApplyDateが出力されるようである。 各項目の説明は以下の通り。 項目 説明 Action リソースで使用可能な保留中のメンテナンスアクションのタイプsystem-update、db-upgrade、hardware-maintenance、とca-certificate-rotation。 Description メンテナンスアクションの詳細を説明 AutoAppliedAfterDate アクションが適用されるメンテナンスウィンドウの日付 CurrentApplyDate 保留中のメンテナンスアクションがリソースに適用される発効日 ForcedApplyDate メンテナンスアクションが自動的に適用される日付。(延期不可) OptInStatus リソースに対して受信されたオプトイン要求のタイプ明示的にapply-pending-maintenance-actionを実行した場合に出力される。“next-maintenance”、“immediate”、“undo-opt-in” OptInStatusのステータスはapply-pending-maintenance-actionで明示的に指定した場合に出力される。もしくはマネージメントコンソール上の「Upgrade at Next Window(次のウィンドウでアップグレード)」や「Upgrade Now(今すぐアップグレード)」を選択する。 [ec2-user@bastin ~]$ aws rds apply-pending-maintenance-action --resource-identifier arn:aws:rds:ap-northeast-1:xxxxxxxxxxxxxx:cluster:neptestdb-cluster --apply-action system-update --opt-in-type next-maintenance 次の通り、OptInStatusが出力されるようになる [ec2-user@bastin ~]$ aws rds describe-pending-maintenance-actions --resource-identifier arn:aws:rds:ap-northeast-1:xxxxxxxxxxxxxx:cluster:neptestdb-cluster { "PendingMaintenanceActions": [ { "PendingMaintenanceActionDetails": [ { "Action": "system-update", "Description": "Engine Patch Upgrade", "CurrentApplyDate": "2020-05-03T15:58:00Z", "AutoAppliedAfterDate": "2020-05-03T15:58:00Z", "OptInStatus": "next-maintenance" } ], "ResourceIdentifier": "arn:aws:rds:ap-northeast-1:xxxxxxx:cluster:xxxxxxx-cluster" } ] } 参考: https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_PendingMaintenanceAction.html https://docs.aws.amazon.com/cli/latest/reference/rds/apply-pending-maintenance-action.html --- ### RDSとAuroraで変更を検討するパラメータ(PostgreSQL) date: 2021-01-21 url: https://zatoima.github.io/aws-aurora-rds-postgresql-parameter-change.html tags: AWS, Aurora, RDS, PostgreSQL はじめに AuroraやRDSはマネージド・サービスなので、パラメータチューニングが不要だが、要件や性能問題次第ではチューニングの必要があるのでそれをまとめたい。 変更を検討するパラメータ一覧 気付いたら都度追加していく。現在のパラメータ(setting列)は、Aurora、RDS共にr5.largeのインスタンスタイプから抽出 変更を検討するパラメータと書きつつ、AuroraとRDSで変更可能なパラメータも異なり、変更できないものもあるので注意。checkpoint_timeout等はチェックポイントチューニングでいじるところではあるが、RDSは変更出来て、Auroraでは変更出来ない模様。 RDSとAurora PostgreSQLで変更不可なパラメータ一覧 | my opinion is my own https://zatoima.github.io/aws-aurora-rds-postgresql-parameter-modifiable.html name setting(Aurora) setting(RDS) boot_val unit context archive_timeout 300 ※変更不可 300 ※変更不可 0 s sighup autovacuum_max_workers 3 3 3 postmaster checkpoint_completion_target 0.5 0.9 0.5 sighup checkpoint_timeout 60 300 ※変更不可 300 s sighup deadlock_timeout 1000 1000 1000 ms superuser effective_io_concurrency 256 1 ※変更不可 256 user lc_messages superuser log_filename postgresql.log.%Y-%m-%d-%H%M postgresql.log.%Y-%m-%d-%H postgresql-%Y-%m-%d_%H%M%S.log sighup log_hostname off on off sighup log_min_duration_statement -1 -1 -1 ms rds_superuser log_rotation_age 60 60 1440 min sighup log_rotation_size 100000 10240 10240 kB sighup log_timezone UTC ※変更不可 UTC ※変更不可 GMT sighup max_connections 1710 1710 100 postmaster max_parallel_maintenance_workers 2 2 2 user max_parallel_workers 8 8 8 user max_parallel_workers_per_gather 2 2 2 user max_worker_processes 8 8 8 postmaster random_page_cost 4 4 4 user shared_buffers 1304235 497507 1024 8kB postmaster superuser_reserved_connections 3 3 3 postmaster wal_buffers 2048 8192 -1 8kB postmaster 抽出用SQL SELECT name, setting, boot_val, unit, context FROM pg_settings WHERE name IN ('max_connections','superuser_reserved_connections','lc_messages','archive_timeout','log_filename','log_rotation_age','log_rotation_size','log_min_duration_statement','log_hostname','log_timezone','shared_buffers','effective_io_concurrency','max_worker_processes','max_parallel_maintenance_workers','max_parallel_workers_per_gather','max_parallel_workers','wal_buffers','checkpoint_timeout','checkpoint_completion_target','random_page_cost','autovacuum_max_workers','deadlock_timeout') ORDER BY 1; パラメータ個別メモ deadlock_timeout デッドロックの検査は負荷が高いので、デフォルトの1000ms(1秒)より上げても良い。 checkpoint_completion_target checkpoint_timeout AuroraとRDSでデフォルトの設定値が異なる。パフォーマンス問題が発生した場合に変更する方向。 ※Auroraはチェックポイント自体の概念が無く、log_bufferに入ってきたメモリは都度ストレージ側に流れていくはずなので、変更の意味があるかは不明。 PostgreSQLのcheckpoint_completion_targetについてメモ | my opinion is my own https://zatoima.github.io/postgresql-about-checkpoint_completion_target.html log_filename log_hostname log_min_duration_statement log_rotation_age log_rotation_size log_timezone ログ要件に応じて変更 max_connections OSS版のPostgreSQLの100と比較するとパラメータは調整されているが、コネクション数自体は要件次第。インスタンスタイプをスケールアップするとmax_connectionsも一緒に上がっていく。 autovacuum_max_workers max_parallel_maintenance_workers max_parallel_workers max_parallel_workers_per_gather max_worker_processes VacuumやAnalyzeのチューニング時に微調整 shared_buffers Auroraの場合は、DB パラメータグループでのデフォルト値は全メモリの75%に設定される。これは、Aurora PostgreSQLがダブルバッファリングを使用しておらず、OS側のファイルシステムキャッシュが必要ないため。他のメモリ系パラメータに振った方が良ければ微調整。 Shared_Buffers DB パラメータのデフォルト値と Amazon RDS PostgreSQL および Aurora PostgreSQL の間に差がある理由を理解する https://aws.amazon.com/jp/premiumsupport/knowledge-center/rds-aurora-postgresql-shared-buffers/ wal_buffers 未だディスクに書き込まれていないWALデータに対して使用される共有メモリ容量。commit時にこのバッファからディスクに書き込まれる。書き込みが多く、CPUが多い場合は数MBに拡張することで効果は得られるが、Aurora、RDS共に基本的にはデフォルト値で問題無さそう。 random_page_cost 非シーケンシャル的に取り出されるディスクページのコストに対するプランナの推測を設定。この値を小さくすることで相対的にインデックススキャンを行うことになる。一般的にランダムリードに関してはHDDよりSDDの方が早いので、SSDの場合は1.0等に設定することもある。場合によってはデフォルトの4.0より下げても良いかも。 インスタンスタイプのスケールアップで変わるパラメータは? 上記のパラメータを対象に何が変わるのか調べてみた。max_connectionsやshared_buffersは変更される。一方でCPU、メモリが増えているにも関わらず、パラレル度の指定やwal_buffers等には変更がない。 name setting(Aurora)※r5.large setting(Aurora)※r5.2xlarge setting(RDS)※r5.large setting(RDS)※r5.2xlarge archive_timeout 300 300 300 300 autovacuum_max_workers 3 3 3 3 checkpoint_completion_target 0.5 0.5 0.9 0.9 checkpoint_timeout 60 60 300 300 deadlock_timeout 1000 1000 1000 1000 effective_io_concurrency 256 256 1 1 lc_messages log_filename postgresql.log.%Y-%m-%d-%H%M postgresql.log.%Y-%m-%d-%H%M postgresql.log.%Y-%m-%d-%H postgresql.log.%Y-%m-%d-%H log_hostname off off on on log_min_duration_statement -1 -1 -1 -1 log_rotation_age 60 60 60 60 log_rotation_size 100000 100000 10240 10240 log_timezone UTC UTC UTC UTC max_connections 1710 5000 1710 5000 max_parallel_maintenance_workers 2 2 2 2 max_parallel_workers 8 8 8 8 max_parallel_workers_per_gather 2 2 2 2 max_worker_processes 8 8 8 8 random_page_cost 4 4 4 4 shared_buffers 1304235 5474754 497507 2029633 superuser_reserved_connections 3 3 3 3 wal_buffers 2048 2048 8192 8192 参考 PostgresqlCO.NF:人間のためのPostgreSQLの設定 https://postgresqlco.nf/doc/ja/param/ PostgreSQL11 設定パラメーター解体新書 / PostgreSQL 11 parameter - Speaker Deck https://speakerdeck.com/ester41/postgresql-11-parameter?slide=2 PostgreSQL安定運用のための障害予防と検知 https://www.ospn.jp/osc2014.enterprise/pdf/OSC2014_Enterprise_hp.pdf PostgreSQL のパフォーマンスチューニング - Qiita https://qiita.com/cuzic/items/f9b846e6171a54079d77 Oracle データベースを Amazon RDS PostgreSQL または Amazon Aurora PostgreSQL に移行する上でのベスト プラクティス: PostgreSQL 環境のターゲット データベースに関する考慮事項 | Amazon Web Services ブログ https://aws.amazon.com/jp/blogs/news/best-practices-for-migrating-an-oracle-database-to-amazon-rds-postgresql-or-amazon-aurora-postgresql-target-database-considerations-for-the-postgresql-environment/ --- ### RDSとAurora PostgreSQLで変更不可なパラメータ一覧 date: 2021-01-20 url: https://zatoima.github.io/aws-aurora-rds-postgresql-parameter-modifiable.html tags: AWS, Aurora, RDS, PostgreSQL はじめに AWSのAuroraとRDS PostgreSQLで変更不可なパラメータに結構差異があってハマりそうだったので、差異をメモしておく。下記のコマンドで抽出して、“変更可能"が"FALSE"を一覧化している。 コマンド RDS PostgreSQL aws rds describe-db-cluster-parameters --db-cluster-parameter-group-name default.aurora-postgresql11 | jq -r '["名前","値","許可された値","変更可能","送信元","適用タイプ","データ型","説明","ApplyMethod","MinimumEngineVersion"], (.Parameters[] | [.ParameterName,.ParameterValue,.AllowedValues,.IsModifiable,.Source,.ApplyType,.DataType,.Description,.ApplyMethod,.MinimumEngineVersion]) | @csv' Aurora PostgreSQL DBクラスターパラメータグループ aws rds describe-db-cluster-parameters --db-cluster-parameter-group-name default.aurora-postgresql11 | jq -r '["名前","値","許可された値","変更可能","送信元","適用タイプ","データ型","説明","ApplyMethod","MinimumEngineVersion"], (.Parameters[] | [.ParameterName,.ParameterValue,.AllowedValues,.IsModifiable,.Source,.ApplyType,.DataType,.Description,.ApplyMethod,.MinimumEngineVersion]) | @csv' Aurpra PostgreSQL DBパラメータグループ aws rds describe-db-parameters --db-parameter-group-name default.aurora-postgresql11 | jq -r '["名前","値","許可された値","変更可能","送信元","適用タイプ","データ型","説明","ApplyMethod","MinimumEngineVersion"], (.Parameters[] | [.ParameterName,.ParameterValue,.AllowedValues,.IsModifiable,.Source,.ApplyType,.DataType,.Description,.ApplyMethod,.MinimumEngineVersion]) | @csv' 変更が出来ないパラメータ一覧 PostgreSQL11を対象。“変更可能"が"FALSE"を一覧化。 ※実際にパラメータが変更可能となっていても、実際の挙動がどうなるのかは注意が必要なはず。例えば、Auroraはチェックポイントの動きがRDS PostgreSQLと違うので、full_page_writesを変更して動作が変わるとは思えない…。 RDS Aurora(DBクラスターパラメータグループ) Aurora(DB パラメータグループ) archive_command archive_command checkpoint_timeout archive_timeout archive_timeout config_file config_file checkpoint_timeout db_user_namespace data_directory config_file effective_io_concurrency db_user_namespace data_directory exit_on_error exit_on_error db_user_namespace hba_file fsync effective_io_concurrency hot_standby_feedback full_page_writes exit_on_error ident_file hba_file hba_file listen_addresses ident_file hot_standby_feedback lo_compat_privileges listen_addresses huge_pages log_directory lo_compat_privileges ident_file log_file_mode log_directory listen_addresses log_line_prefix log_file_mode lo_compat_privileges log_timezone logging_collector log_directory log_truncate_on_rotation log_line_prefix log_file_mode logging_collector log_timezone logging_collector rds.superuser_variables log_truncate_on_rotation log_line_prefix restart_after_crash port log_timezone ssl_ca_file rds.extensions log_truncate_on_rotation ssl_cert_file rds.max_tcp_buffers min_wal_size ssl_ciphers rds.superuser_variables port ssl_key_file restart_after_crash rds.extensions stats_temp_directory server_encoding rds.superuser_variables superuser_reserved_connections ssl_ca_file restart_after_crash syslog_facility ssl_cert_file server_encoding unix_socket_directories ssl_ciphers ssl_ca_file unix_socket_group ssl_key_file ssl_cert_file unix_socket_permissions stats_temp_directory ssl_ciphers wal_receiver_status_interval superuser_reserved_connections ssl_key_file syslog_facility stats_temp_directory unix_socket_directories superuser_reserved_connections unix_socket_group syslog_facility unix_socket_permissions unix_socket_directories wal_sync_method unix_socket_group unix_socket_permissions wal_receiver_status_interval --- ### WindowsのローカルPCからCodeCommitを使う初期手順 date: 2021-01-18 url: https://zatoima.github.io/aws-codecommit-git-for-windows.html tags: AWS, git IAMユーザ作成 IAMユーザを作成して下記の管理ポリシーをアタッチする。 AWSCodeCommitPowerUser CodeCommit でのアイデンティティベースのポリシー (IAM ポリシー) の使用 - AWS CodeCommit https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/auth-and-access-control-iam-identity-based-access-control.html#managed-policies-poweruser Gitをインストール 既にインストールされているので省略。 C:\Users\imazaj>git --version git version 2.30.0.windows.2 ダウンロードであれば下記から。 Git - Downloads http://git-scm.com/downloads Git と CodeCommit 用のパブリックキーとプライベートキーの設定 Git for WindowsのGit Bashを立ち上げssh-keygenコマンドで鍵ファイルを作成 $ ssh-keygen Generating public/private rsa key pair. ~省略~ C:\Users\imazaj>dir C:\Users\imazaj\.ssh 2019/12/17 15:47 <DIR> . 2019/12/17 15:47 <DIR> .. 2021/01/15 20:39 2,610 id_rsa 2021/01/15 20:39 575 id_rsa.pub 2019/12/17 15:47 799 known_hosts IAMユーザの"認証情報"タブに移動して、AWS CodeCommit の SSH キーに公開鍵ファイルをアップロードする。 公開鍵情報を貼り付けてアップロード SSHパブリックキーIDを控える。 ~/.ssh/configを作成して、下記情報を入力。UserはSSHパブリックキーID。IdentityFileは秘密鍵を指定。 Host git-codecommit.*.amazonaws.com User xxxxxxxxxxxxxxxxxxx IdentityFile ~/.ssh/id_rsa SSH設定の確認 ssh git-codecommit.us-east-2.amazonaws.com リポジトリのクローンを作成 toolrepoというリポジトリに、README.mdを作成済 C:\Users\imazaj>git clone ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/toolrepo Cloning into 'toolrepo'... Warning: Permanently added the RSA host key for IP address 'xxxxxxxxxxxx' to the list of known hosts. remote: Counting objects: 3, done. Receiving objects: 100% (3/3), 215 bytes | 23.00 KiB/s, done. C:\Users\imazaj\toolrepo>dir ドライブ C のボリューム ラベルは OSDisk です ボリューム シリアル番号は E49E-5113 です C:\Users\imazaj\toolrepo のディレクトリ 2021/01/15 20:56 <DIR> . 2021/01/15 20:56 <DIR> .. 2021/01/15 20:56 0 README.md 1 個のファイル 0 バイト 2 個のディレクトリ 3,597,164,544 バイトの空き領域 README.mdを編集してcommit C:\Users\imazaj\toolrepo>git status On branch master Your branch is up to date with 'origin/master'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: README.md no changes added to commit (use "git add" and/or "git commit -a") C:\Users\imazaj\toolrepo>git add README.md C:\Users\imazaj\toolrepo>git commit -m "first commit" [master 2ab1525] first commit 1 file changed, 1 insertion(+) C:\Users\imazaj\toolrepo>git push Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Writing objects: 100% (3/3), 252 bytes | 252.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 To ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/toolrepo 357bc6c..2ab1525 master -> master 参考 Windows で AWS CodeCommit リポジトリへの SSH 接続をセットアップする手順 - AWS CodeCommit https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/setting-up-ssh-windows.html --- ### git for windowsのアップデートコマンド date: 2021-01-16 url: https://zatoima.github.io/git-update-command.html tags: git, その他 コマンド一発。 C:\Users\imazaj>git update-git-for-windows Git for Windows 2.26.2.windows.1 (64bit) Update 2.30.0.windows.2 is available Download and install Git for Windows 2.30.0(2) [N/y]? y ################################################################################################################ 100.0%################################################################################################################# 100.0% GUIがポップアップされるので、デフォルト設定でインストール(アップデート) Git for Windows https://gitforwindows.org/ --- ### Aurora PostgreSQLにHammerDBのTPC-Hを実行 date: 2021-01-15 url: https://zatoima.github.io/aws-aurora-postgresql-hammerdb-benchmark-tpc-h.html tags: AWS, Aurora, PostgreSQL TPC-HをAurora PostgreSQLに対して実行する。 TPC-Cについては下記を参照。 Aurora PostgreSQLにHammerDBのTPC-Cを実行 | my opinion is my own https://zatoima.github.io/aws-aurora-postgresql-hammerdb-benchmark.html はじめに CLI実行とのことで、下記のHammerDBのドキュメントを参考 Chapter 8. Command Line Interface (CLI) https://hammerdb.com/docs/ch08.html 事前準備 PostgreSQL関連のライブラリが既にインストールされていることを前提。無ければ下記でインストールしておく。 sudo yum -y install postgresql sudo yum -y install postgresql-contrib HammerDBのインストーラーダウンロード wget https://github.com/TPC-Council/HammerDB/releases/download/v3.3/HammerDB-3.3-Linux.tar.gz tar xvzf HammerDB-3.3-Linux.tar.gz cd HammerDB-3.3 HammerDB https://hammerdb.com/download.html ライブラリ確認 PostgreSQLのライブラリのチェックのSuccessを確認する。 Checking database library for PostgreSQL Success ... loaded library Pgtcl for PostgreSQL [ec2-user@bastin HammerDB-3.3]$ ls -l total 100 drwxr-xr-x 2 ec2-user ec2-user 19 Oct 18 2019 agent drwxr-xr-x 2 ec2-user ec2-user 37 Oct 21 2019 bin -rwxr-xr-x 1 ec2-user ec2-user 29218 Oct 16 2019 ChangeLog drwxr-xr-x 2 ec2-user ec2-user 178 Oct 16 2019 config -rwxr-xr-x 1 ec2-user ec2-user 7274 Oct 16 2019 hammerdb -rwxr-xr-x 1 ec2-user ec2-user 3167 Oct 16 2019 hammerdbcli -rwxr-xr-x 1 ec2-user ec2-user 2508 Oct 16 2019 hammerdbws drwxr-xr-x 2 ec2-user ec2-user 39 Jul 19 2019 images drwxr-xr-x 2 ec2-user ec2-user 4096 Oct 21 2019 include drwxr-xr-x 21 ec2-user ec2-user 4096 Oct 21 2019 lib -rwxr-xr-x 1 ec2-user ec2-user 34666 Jul 19 2019 license drwxr-xr-x 2 ec2-user ec2-user 4096 Oct 16 2019 modules -rwxr-xr-x 1 ec2-user ec2-user 116 Oct 16 2019 readme drwxr-xr-x 10 ec2-user ec2-user 126 Jul 19 2019 src [ec2-user@bastin HammerDB-3.3]$ ./hammerdbcli HammerDB CLI v3.3 Copyright (C) 2003-2019 Steve Shaw Type "help" for a list of commands The xml is well-formed, applying configuration hammerdb>librarycheck Checking database library for Oracle Error: failed to load Oratcl - can't read "env(ORACLE_HOME)": no such variable Ensure that Oracle client libraries are installed and the location in the LD_LIBRARY_PATH environment variable Checking database library for MSSQLServer Error: failed to load tdbc::odbc - couldn't load file "libiodbc.so": libiodbc.so: cannot open shared object file: No such file or directory Ensure that MSSQLServer client libraries are installed and the location in the LD_LIBRARY_PATH environment variable Checking database library for Db2 Error: failed to load db2tcl - couldn't load file "/home/ec2-user/HammerDB-3.3/lib/db2tcl2.0.0/libdb2tcl.so.0.0.1": libdb2.so.1: cannot open shared object file: No such file or directory Ensure that Db2 client libraries are installed and the location in the LD_LIBRARY_PATH environment variable Checking database library for MySQL Error: failed to load mysqltcl - couldn't load file "/home/ec2-user/HammerDB-3.3/lib/mysqltcl-3.052/libmysqltcl3.052.so": libmysqlclient.so.21: cannot open shared object file: No such file or directory Ensure that MySQL client libraries are installed and the location in the LD_LIBRARY_PATH environment variable Checking database library for PostgreSQL Success ... loaded library Pgtcl for PostgreSQL Checking database library for Redis Success ... loaded library redis for Redis HammerDBのパラメータ設定 接続DBをPostgreSQL 指定 hammerdb> dbset db pg 対象ベンチマークをTPC-Cに設定する hammerdb> dbset bm TPC-H 接続先ホスト名の設定 hammerdb> diset connection pg_host aurorav1.cluster-cm678nkt5thr.ap-northeast-1.rds.amazonaws.com superuserのユーザ名、パスワードの設定 hammerdb> diset tpch pg_tpch_superuser postgres hammerdb> diset tpch pg_tpch_superuserpass postgres pg_count_ware(スケールファクター)の設定 データ容量を調整する。 hammerdb> diset tpch pg_scale_fact 1 テストスキーマ構築を実行するユーザー数の設定 hammerdb> diset tpch pg_num_tpch_threads 4 設定値を確認 hammerdb>print dict Dictionary Settings for PostgreSQL connection { pg_host = aurorav1.cluster-cm678nkt5thr.ap-northeast-1.rds.amazonaws.com pg_port = 5432 } tpch { pg_scale_fact = 1 pg_tpch_superuser = postgres pg_tpch_superuserpass = postgres pg_tpch_defaultdbase = postgres pg_tpch_user = tpch pg_tpch_pass = tpch pg_tpch_dbase = tpch pg_tpch_gpcompat = false pg_tpch_gpcompress = false pg_num_tpch_threads = 4 pg_total_querysets = 1 pg_raise_query_error = false pg_verbose = false pg_refresh_on = false pg_degree_of_parallel = 2 pg_update_sets = 1 pg_trickle_refresh = 1000 pg_refresh_verbose = false pg_cloud_query = false pg_rs_compat = false } スキーマ作成 スキーマ作成、及び、テストデータの投入 データロードが走るので時間が掛かる。 hammerdb>buildschema Script cleared Building 1 Warehouses(s) with 1 Virtual User Ready to create a 1 Warehouse PostgreSQL TPC-C schema in host xxxxxx.CLUSTER-xxxxxxxx.AP-NORTHEAST-1.RDS.AMAZONAWS.COM:5432 under user TPCC in database TPCC? Enter yes or no: replied yes Vuser 1 created - WAIT IDLE RUNNING - TPC-C creation Vuser 1:RUNNING Vuser 1:CREATING TPCC SCHEMA Vuser 1:CREATING DATABASE tpcc under OWNER tpcc ~省略~ Vuser 1:GATHERING SCHEMA STATISTICS Vuser 1:TPCC SCHEMA COMPLETE Vuser 1:FINISHED SUCCESS ALL VIRTUAL USERS COMPLETE TPC-C Driver Script hammerdb> スケールファクタを10倍に設定して、完了後にPostgreSQL側のtpccデータベースにログインして確認すれば9つのテーブルが作成されていることがわかる。 postgres@aurorapgsqlv1:tpcc> \dt+ +----------+------------+--------+---------+---------+---------------+ | Schema | Name | Type | Owner | Size | Description | |----------+------------+--------+---------+---------+---------------| | public | customer | table | tpcc | 371 MB | <null> | | public | district | table | tpcc | 168 kB | <null> | | public | history | table | tpcc | 56 MB | <null> | | public | item | table | tpcc | 21 MB | <null> | | public | new_order | table | tpcc | 7864 kB | <null> | | public | order_line | table | tpcc | 656 MB | <null> | | public | orders | table | tpcc | 43 MB | <null> | | public | stock | table | tpcc | 710 MB | <null> | | public | warehouse | table | tpcc | 40 kB | <null> | +----------+------------+--------+---------+---------+---------------+ SELECT 9 Time: 0.021s ロード用のクライアントプロセスをkillする hammerdb>vudestroy Destroying Virtual Users Virtual Users Destroyed vudestroy success スクリプトのロード hammerdb>loadscript TPC-C Driver Script Script loaded, Type "print script" to view テスト実行用クライアント(Virtual User)の設定、作成 hammerdb>vuset vu 4 hammerdb>vuset logtotemp 1 hammerdb>vuset showoutput 1 hammerdb>vuset unique 1 hammerdb>vuset timestamps 1 hammerdb>print vuconf Virtual Users = 4 User Delay(ms) = 500 Repeat Delay(ms) = 500 Iterations = 1 Show Output = 1 Log Output = 1 Unique Log Name = 1 No Log Buffer = 0 Log Timestamps = 1 hammerdb> hammerdb> vucreate Vuser 1 created MONITOR - WAIT IDLE Vuser 2 created - WAIT IDLE Vuser 3 created - WAIT IDLE Vuser 4 created - WAIT IDLE Vuser 5 created - WAIT IDLE Logging activated to /tmp/hammerdb_5FADF0FE5B3F03E293835333.log 5 Virtual Users Created with Monitor VU hammerdb>vustatus 1 = WAIT IDLE 2 = WAIT IDLE 3 = WAIT IDLE 4 = WAIT IDLE 5 = WAIT IDLE HammerDBの実行前の準備 下記のような理由からこの状態でHammerDBを実行していくと中々終わらないみたいなので、ひと手間加えていく。 HammerDBをCLIで使うなど(8):PostgreSQLにTPC-Hを実行してみる - なからなLife https://atsuizo.hatenadiary.jp/entry/2019/09/04/090000 作成されるインデックスが、MySQL用と異なっているからー! 例えば、TPC-Hで一番大きいテーブル「LINEITEM」には、以下のようにPARTSUPPテーブルを参照する外部キー制約が付与されています。 CONSTRAINT lineitem_partsupp_fk FOREIGN KEY (l_partkey, l_suppkey) REFERENCES public.partsupp (ps_partkey, ps_suppkey) PostgreSQLでは 外部キーは主キーであるかまたは一意性制約を構成する列を参照しなければなりません。 これは、被参照列は常に(主キーまたは一意性制約の基礎となる)インデックスを持つことを意味します。 このため、参照行に一致する行があるかどうかのチェックは効率的です。 被参照テーブルからの行のDELETEや被参照行のUPDATEは、古い値と一致する行に対して参照テーブルのスキャンが必要となるので、参照行にもインデックスを付けるのは大抵は良い考えです。 これは常に必要という訳ではなく、また、インデックスの方法には多くの選択肢がありますので、外部キー制約の宣言では参照列のインデックスが自動的に作られるということはありません。 5.3. 制約 ということで、PARTSUPPテーブルの(ps_partkey, ps_suppkey列には主キー制約が適用されている=インデックスも存在するものの、LINEITEMのl_partkey, l_suppkey列には、インデックスがない状態です。 SQL-20では、LINEITEMテーブルのl_partkey, l_suppkeyついて、PARTSUPPテーブルのps_partkey, ps_suppkeyに対するFKが張ってあり、これを使って結合されているのですが、l_partkey, l_suppkeyに自体にはインデックスが張ってないんで、フルスキャン(SeqScan)になっています。 そして、この外部参照の関係にある列で結合して絞り込んだ結果を集約関数で処理するサブクエリの実行コストが異常に大きな値となります。 というわけで、実行前にtpchユーザでtpchデータベースにログインして、下記のインデックスを作成する。 CREATE INDEX ON customer (C_NATIONKEY); CREATE INDEX ON lineitem (L_ORDERKEY); CREATE INDEX ON lineitem (L_SUPPKEY); CREATE INDEX ON lineitem (L_PARTKEY,L_SUPPKEY); CREATE INDEX ON nation (N_REGIONKEY); CREATE INDEX ON orders (O_CUSTKEY); CREATE INDEX ON partsupp (PS_PARTKEY); CREATE INDEX ON partsupp (PS_SUPPKEY); CREATE INDEX ON supplier (S_NATIONKEY); CREATE INDEX ON lineitem (L_SHIPDATE); CREATE INDEX ON lineitem (L_COMMITDATE); CREATE INDEX ON lineitem (L_RECEIPTDATE); CREATE INDEX ON orders (O_ORDERDATE); HammerDBの実行 hammerdb> vurun 実行結果 hammerdb>vurun RUNNING - PostgreSQL TPC-H Vuser 1:RUNNING Vuser 1:Executing Query 21 (1 of 22) Vuser 2:RUNNING Vuser 2:Executing Query 6 (1 of 22) Vuser 3:RUNNING Vuser 3:Executing Query 8 (1 of 22) Vuser 4:RUNNING Vuser 4:Executing Query 5 (1 of 22) Vuser 2:query 6 completed in 3.016 seconds Vuser 2:Executing Query 17 (2 of 22) Vuser 4:query 5 completed in 2.78 seconds Vuser 4:Executing Query 21 (2 of 22) Vuser 1:query 21 completed in 5.485 seconds Vuser 1:Executing Query 3 (2 of 22) Vuser 1:query 3 completed in 2.953 seconds Vuser 1:Executing Query 18 (3 of 22) Vuser 4:query 21 completed in 5.661 seconds Vuser 4:Executing Query 14 (3 of 22) Vuser 3:query 8 completed in 9.447 seconds Vuser 3:Executing Query 5 (2 of 22) Vuser 4:query 14 completed in 1.777 seconds Vuser 4:Executing Query 19 (4 of 22) Vuser 4:query 19 completed in 0.348 seconds Vuser 4:Executing Query 15 (5 of 22) Vuser 3:query 5 completed in 2.148 seconds Vuser 3:Executing Query 4 (3 of 22) Vuser 2:query 17 completed in 9.567 seconds Vuser 2:Executing Query 14 (3 of 22) Vuser 3:query 4 completed in 0.81 seconds Vuser 3:Executing Query 6 (4 of 22) Vuser 2:query 14 completed in 1.566 seconds Vuser 2:Executing Query 16 (4 of 22) Vuser 3:query 6 completed in 2.785 seconds Vuser 3:Executing Query 17 (5 of 22) Vuser 2:query 16 completed in 7.821 seconds Vuser 2:Executing Query 19 (5 of 22) Vuser 2:query 19 completed in 0.243 seconds Vuser 2:Executing Query 10 (6 of 22) Vuser 3:query 17 completed in 8.858 seconds Vuser 3:Executing Query 7 (6 of 22) Vuser 3:query 7 completed in 3.284 seconds Vuser 3:Executing Query 1 (7 of 22) Vuser 4:query 15 completed in 17.023 seconds Vuser 4:Executing Query 17 (6 of 22) Vuser 2:query 10 completed in 6.98 seconds Vuser 2:Executing Query 9 (7 of 22) Vuser 1:query 18 completed in 26.544 seconds Vuser 1:Executing Query 5 (4 of 22) Vuser 1:query 5 completed in 2.252 seconds Vuser 1:Executing Query 11 (5 of 22) Vuser 1:query 11 completed in 0.781 seconds Vuser 1:Executing Query 7 (6 of 22) Vuser 2:query 9 completed in 9.707 seconds Vuser 2:Executing Query 2 (8 of 22) Vuser 1:query 7 completed in 2.585 seconds Vuser 1:Executing Query 6 (7 of 22) Vuser 4:query 17 completed in 13.075 seconds Vuser 4:Executing Query 12 (7 of 22) Vuser 1:query 6 completed in 2.757 seconds Vuser 1:Executing Query 20 (8 of 22) Vuser 1:query 20 completed in 0.943 seconds Vuser 1:Executing Query 17 (9 of 22) Vuser 2:query 2 completed in 5.946 seconds Vuser 2:Executing Query 15 (9 of 22) Vuser 4:query 12 completed in 3.236 seconds Vuser 4:Executing Query 6 (8 of 22) Vuser 4:query 6 completed in 2.542 seconds Vuser 4:Executing Query 4 (9 of 22) Vuser 3:query 1 completed in 20.678 seconds Vuser 3:Executing Query 18 (8 of 22) Vuser 4:query 4 completed in 0.767 seconds Vuser 4:Executing Query 9 (10 of 22) Vuser 1:query 17 completed in 13.149 seconds Vuser 1:Executing Query 12 (10 of 22) Vuser 1:query 12 completed in 3.912 seconds Vuser 1:Executing Query 16 (11 of 22) Vuser 4:query 9 completed in 13.335 seconds Vuser 4:Executing Query 8 (11 of 22) Vuser 4:query 8 completed in 1.575 seconds Vuser 4:Executing Query 16 (12 of 22) Vuser 2:query 15 completed in 18.843 seconds Vuser 2:Executing Query 8 (10 of 22) Vuser 2:query 8 completed in 0.921 seconds Vuser 2:Executing Query 5 (11 of 22) Vuser 2:query 5 completed in 1.495 seconds Vuser 2:Executing Query 22 (12 of 22) Vuser 2:query 22 completed in 0.785 seconds Vuser 2:Executing Query 12 (13 of 22) Vuser 1:query 16 completed in 9.12 seconds Vuser 1:Executing Query 15 (12 of 22) Vuser 2:query 12 completed in 3.083 seconds Vuser 2:Executing Query 7 (14 of 22) Vuser 4:query 16 completed in 8.094 seconds Vuser 4:Executing Query 11 (13 of 22) Vuser 4:query 11 completed in 0.576 seconds Vuser 4:Executing Query 2 (14 of 22) Vuser 2:query 7 completed in 2.229 seconds Vuser 2:Executing Query 13 (15 of 22) Vuser 3:query 18 completed in 26.223 seconds Vuser 3:Executing Query 22 (9 of 22) Vuser 3:query 22 completed in 0.718 seconds Vuser 3:Executing Query 14 (10 of 22) Vuser 4:query 2 completed in 4.166 seconds Vuser 4:Executing Query 10 (15 of 22) Vuser 3:query 14 completed in 1.276 seconds Vuser 3:Executing Query 9 (11 of 22) Vuser 2:query 13 completed in 6.832 seconds Vuser 2:Executing Query 18 (16 of 22) Vuser 4:query 10 completed in 7.385 seconds Vuser 4:Executing Query 18 (16 of 22) Vuser 3:query 9 completed in 11.277 seconds Vuser 3:Executing Query 10 (12 of 22) Vuser 1:query 15 completed in 18.736 seconds Vuser 1:Executing Query 13 (13 of 22) Vuser 3:query 10 completed in 7.917 seconds Vuser 3:Executing Query 15 (13 of 22) Vuser 1:query 13 completed in 13.717 seconds Vuser 1:Executing Query 10 (14 of 22) Vuser 1:query 10 completed in 7.634 seconds Vuser 1:Executing Query 2 (15 of 22) Vuser 2:query 18 completed in 33.341 seconds Vuser 2:Executing Query 1 (17 of 22) Vuser 1:query 2 completed in 4.614 seconds Vuser 1:Executing Query 8 (16 of 22) Vuser 1:query 8 completed in 1.044 seconds Vuser 1:Executing Query 14 (17 of 22) Vuser 4:query 18 completed in 33.215 seconds Vuser 4:Executing Query 1 (17 of 22) Vuser 1:query 14 completed in 1.698 seconds Vuser 1:Executing Query 19 (18 of 22) Vuser 1:query 19 completed in 0.303 seconds Vuser 1:Executing Query 9 (19 of 22) Vuser 3:query 15 completed in 26.017 seconds Vuser 3:Executing Query 11 (14 of 22) Vuser 3:query 11 completed in 1.312 seconds Vuser 3:Executing Query 20 (15 of 22) Vuser 3:query 20 completed in 1.176 seconds Vuser 3:Executing Query 2 (16 of 22) Vuser 1:query 9 completed in 11.02 seconds Vuser 1:Executing Query 22 (20 of 22) Vuser 1:query 22 completed in 1.261 seconds Vuser 1:Executing Query 1 (21 of 22) Vuser 3:query 2 completed in 6.488 seconds Vuser 3:Executing Query 21 (17 of 22) Vuser 3:query 21 completed in 9.238 seconds Vuser 3:Executing Query 19 (18 of 22) Vuser 3:query 19 completed in 0.417 seconds Vuser 3:Executing Query 13 (19 of 22) Vuser 2:query 1 completed in 28.195 seconds Vuser 2:Executing Query 4 (18 of 22) Vuser 2:query 4 completed in 1.517 seconds Vuser 2:Executing Query 20 (19 of 22) Vuser 2:query 20 completed in 1.775 seconds Vuser 2:Executing Query 3 (20 of 22) Vuser 4:query 1 completed in 27.942 seconds Vuser 4:Executing Query 13 (18 of 22) Vuser 2:query 3 completed in 5.823 seconds Vuser 2:Executing Query 11 (21 of 22) Vuser 2:query 11 completed in 0.55 seconds Vuser 2:Executing Query 21 (22 of 22) Vuser 3:query 13 completed in 10.16 seconds Vuser 3:Executing Query 16 (20 of 22) Vuser 4:query 13 completed in 9.648 seconds Vuser 4:Executing Query 7 (19 of 22) Vuser 4:query 7 completed in 2.796 seconds Vuser 4:Executing Query 22 (20 of 22) Vuser 2:query 21 completed in 7.339 seconds Vuser 2:Completed 1 query set(s) in 157 seconds Vuser 2:FINISHED SUCCESS Vuser 1:query 1 completed in 27.607 seconds Vuser 1:Executing Query 4 (22 of 22) Vuser 4:query 22 completed in 0.616 seconds Vuser 4:Executing Query 3 (21 of 22) Vuser 1:query 4 completed in 0.512 seconds Vuser 1:Completed 1 query set(s) in 159 seconds Vuser 1:FINISHED SUCCESS Vuser 3:query 16 completed in 8.796 seconds Vuser 3:Executing Query 12 (21 of 22) Vuser 4:query 3 completed in 1.766 seconds Vuser 4:Executing Query 20 (22 of 22) Vuser 4:query 20 completed in 0.292 seconds Vuser 4:Completed 1 query set(s) in 158 seconds Vuser 4:FINISHED SUCCESS Vuser 3:query 12 completed in 1.208 seconds Vuser 3:Executing Query 3 (22 of 22) Vuser 3:query 3 completed in 0.941 seconds Vuser 3:Completed 1 query set(s) in 161 seconds Vuser 3:FINISHED SUCCESS ALL VIRTUAL USERS COMPLETE TPC-H Driver Script hammerdb> クリーンアップ hammerdb>vucomplete true hammerdb>vudestroy Destroying Virtual Users Virtual Users Destroyed vudestroy success hammerdb>clearscript Script cleared 参考 HammerDBをCLIで使うなど(8):PostgreSQLにTPC-Hを実行してみる - なからなLife https://atsuizo.hatenadiary.jp/entry/2019/09/04/090000 Chapter 8. Command Line Interface (CLI) https://hammerdb.com/docs/ch08.html --- ### PythonのSeleniumのElementClickInterceptedExceptionエラーを無理矢理回避する date: 2021-01-14 url: https://zatoima.github.io/python-selenium-error-elementclickinterceptedexception.html tags: Python, Selenium MoneyForwardに自動連携出来ない資産は手動登録しているが、Pythonで自動化している。たまに動かす程度。 エラー Traceback (most recent call last): File "rsu_update_mf.py", line 149, in <module> main() File "rsu_update_mf.py", line 15, in main update_mf() File "rsu_update_mf.py", line 125, in update_mf el.click() File "/usr/local/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 80, in click self._execute(Command.CLICK_ELEMENT) File "/usr/local/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 633, in _execute return self._parent.execute(command, params) File "/usr/local/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute self.error_handler.check_response(response) File "/usr/local/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response raise exception_class(message, screen, stacktrace) selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <img alt="変更" title="変更" src="/assets/bs/button_table_modify-080cf95d1e7394350cd7e97a2f8827168361a221ecbd7bb21efd62c239ce7183.png"> is not clickable at point (754, 570). Other element would receive the click: <a href="https://support.me.moneyforward.com/hc/ja">...</a> (Session info: headless chrome=87.0.4280.88) 原因 seleniumのヘッドレスモードでやっていたのでスクショを取ってみたが、どうやらこの「ヘルプ・サポート」のオブジェクトがクリックしたいオブジェクトと重なっていた模様。 解決方法 window_sizeを別の値に変更して、この「ヘルプ・サポート」のオブジェクトが重ならないように変更 driver.set_window_size(1500,1500) --- ### 準委任契約と請負契約の違い date: 2021-01-13 url: https://zatoima.github.io/contracts-memo.html tags: その他 業務委託契約には「請負契約」と「準委任契約」がある。ここの2つの契約についてメモ。 請負契約 準委任契約 受注者の義務 仕事の完成義務 善管注意義務 成果物の納品 必須 必須ではない 報酬のタイミング 成果物の引き渡しと同時 事務行為が完了した後 瑕疵担保責任 有り 規定無し 中途解約 発注者は契約を解除可 いつでも契約を解除可 再委託 可能 再委託などは原則として出来ない --- ### 『AWS Certified Machine Learning – Specialty』に向けた機械学習勉強メモ date: 2020-12-17 url: https://zatoima.github.io/aws-machine-learning-study.html tags: AWS, 機械学習 はじめに 『AWS Certified Machine Learning – Specialty』に向けて勉強したことをまとめる。主に機械学習の(主に用語)の勉強メモです。書きなぐっているだけ。 用語メモ 説明変数 因果関係における原因、関数における入力。y=f(x)におけるxを説明変数と呼ぶ 目的変数 因果関係における結果、関数における出力。y=f(x)におけるyを目的変数と呼ぶ 線形回帰 ある変数xが与えられたとき、それと相関関係のあるyの値を説明・予測 ロジスティック回帰 ロジスティック関数の形は以下となる。0〜1の値を取り、単調増加 活性化関数 多くの活性化関数が存在する。目的は入力値を別の数値に変換して出力する。 シグモイド関数 0~1の間の値を取る。2分類を行う際によく使われる。0や1に近づければ近づくほど滑らかになる 過学習 与えられたデータに(ノイズ含めて)過度に適合してしまい、訓練データに対する誤差は少ないが、未知データに対する性能が低下してしまう状態 汎化性能 未知のデータに対する性能(汎化性能)。定量化した汎化誤差を小さくすることが重要 正規化 特徴量の値の範囲を一定の範囲におさめる変換。主に[0, 1]か、[-1, 1]の範囲内。 正則化 過学習を防ぐ 極端と思われるデータは対象としない L1正則化(Lasso回帰):極端なデータの重みを0にする L2正則化(Ridge回帰):極端なデータの重みを0に近づける 機械学習における正則化の意味を分かりやすく説明する - Qiita https://qiita.com/kenta1984/items/91ab29fae8cd3920cf2b ドロップアウト ランダムにノードを非活性にして学習する。データは同じだが、毎回異なるデータを学習するので違う重み付けを行う。 ホールドアウト検証 データを学習用データとテスト用データにある割合で分割して検証 K分割交差検証(K-fold cross-validation) データセットをK個に分けてそれぞれで学習した結果を総合評価する。すべてのデータが検証データとなるようにパターンを分けて実行 アンサンブル学習 個々に学習した複数の学習器を融合させて汎化能力を高める機械学習の技術 バギング ブートストラップ法を使って全データから訓練データを複数組、生成する。ブートストラップ法とは母集団から重複込みでランダムにデータを取り出す方法 ブースティング 訓練データを一つ目のモデルに学習させ、予測結果と実際の値を比較する。次のモデルを学習する際には、間違えた部分を正解できるように学習したデータを重視して学習を行う 教師あり学習 学習データに正解ラベルをつけて学習する方法 回帰 各データに対して、データの関係性を表す線(関数)を見出すこと ベイズ線形回帰 ベイズ確率:個人の主観が入った確率のこと 信頼度(確信度)によって分布が異なってくる ベイズ線形回帰はベイズ確率を使い、信頼度の高そうなデータと信頼度の低そうなデータ(ノイズの可能性がある)を同等に扱わず、重みを変える L1、L2正則化と同様のアプローチとなる サポートベクター回帰(SVM) 教師あり学習によるパターン認識モデル サポートベクター(ベクトル) 境界に最も近いデータの点のことを指す。 マージン サポートベクトルと境界との距離を指す サポートベクター回帰ではマージンの最大化という基準で分類を行う 下記図の場合、縦のラインよりも斜めの線の幅が広い。この状態のことをマージンの最大化という。 誤差(ノイズ)対策を行って過学習を防止する。マージンの考えを使って、誤差に不感帯(川の幅)を設けることでノイズの影響を受けにくくする ソフトマージンSVM 誤差を認めるとよりよい線形分離が出来るデータを使う(=明確な分離を目指さない) ランダムフォレスト 決定木ベースのアルゴリズム 下記ステップでアウトプットを得る。アンサンブル学習 データからランダムサンプリング(バギング)でn組のデータを作る それぞれの決定木を作成 決定木の結果を統合 匂配ブースティング 決定木を利用して予測。次に訓練セットと正解データの予測結果の差を取り、誤差を算出。この誤差を正解データとして、決定木を使って2回目の予測を行う。 k近傍法 分類で使用される教師あり学習のアルゴリズム データを多数決で分類 数値データの整形 離散化 連続した値を区分に分ける。 例:来場者の年齢を年代ごとに分ける。 分類 2項分類:例えば正常と異常と分類する ロジスティック回帰 電子メールがスパムであるかどうか、またはトランザクションが不正であるかどうか等 発生確率を予測して確率に応じてYes/Noで分類するもの 多項分類:3つ以上に分類する k近傍法 ある未知の値を最も近いグループの仲間とする分類法 学習データをベクトル空間上にプロットしておき、未知のデータが得られたら、そこから距離が近い順に任意のK個を取得し、多数決でデータが属するクラスを推定する。 下図の場合、クラス判別の流れは以下となる。 1 既知のデータ(学習データ)を黄色と紫の丸としてプロットしておく。 2 Kの数を決めておく。K=3とか。 3 未知のデータとして赤い星が得られたら、近い点から3つ取得する。 4 その3つのクラスの多数決で、属するクラスを推定。 今回は、未知の赤い星はClass Bに属すると推定する。 k近傍法 - Wikipedia https://ja.wikipedia.org/wiki/K%E8%BF%91%E5%82%8D%E6%B3%95 回帰モデルにおける代表的な予測誤差集計方法 R^2(決定係数) 予測誤差を正規化(数値の大きさなどを揃えること)することで得られる指標。全く予測できていない場合は0、全て予測出来ている場合を1として大きいほどよい性能とする RMSE(平方平均二乗誤差) 予測誤差を二乗して平均したあとに集計する指標で、小さいほどよい性能であることを示す。 MAE(平均絶対誤差) 予測誤差の絶対値を平均したあとに集計する指標。 ハイパーパラメータの自動チューニング グリッドサーチ すべてのハイパーパラメータ候補の組み合わせを試行して、最も性能のよいものを選択するという方法。計算量が増えていくので利用が困難。 ランダムサーチ ハイパーパラメータの組み合わせをランダムに試行する。 ベイズ最適化 ガウス過程という回帰モデルを利用して良いハイパーパラメータを探索する手法。試しにいくつかのパラメータ候補で精度を計算して、その結果をもとに更に精度が高くなりそうなパラメータ候補を推定して効率的に探索する 教師なし学習 学習データにラベルをつけないで学習する方法 クラスタリング 階層的クラスタリング 特徴の似ているクラスタ同士を1つずつ結合させていき、最終的に1つの大きなクラスタになるまで繰り返すことでクラスタリングを行う手法 非階層的クラスタリング はじめにクラスタ数を設定して、そのクラスタ数で最もよくデータを分けることができるようクラスタリングを行う手法 様々なデータから似ているデータを集めてグループ化する k平均法(k-means) k-means法を理解する - Qiita https://qiita.com/g-k/items/0d5d22a12a4507ecbf11 ガウス分布(正規分布) 次元削減 次元:特徴量の数 次元削減は「目的(分類や回帰)を達成できる限りの最小の次元にして、次元数を削減すること 特徴選択 考えられる特徴の中から有用なものを厳選する 次元削減 Lasso回帰や決定木などを使って取り除いても影響のない次元を見つけ出し、これを削減する 主成分分析(PCA:Principal Component Analysis) データ全体の分布を近似した新たな指標を合成して次元を削減する t分布型確率的近傍埋め込み法 高次元データの可視化のため2次元または3次元の低次元空間へ埋め込みに最適な非線形次元削減手法 分類とクラスタリングの違い 機械学習の分類とアルゴリズム 損失関数 機械学習の教師あり学習では、データセット (x, y) が与えられたとき、パラメーター θ を持つ関数 f(x; θ) の出力値が y に近くなるように学習を行う。このとき、関数 f の出力値と実際の y の値の差 二乗誤差 データセット (x, y) が与えられたとき、機械学習で得られた回帰モデルの関数を f としたとき、損失関数(二乗誤差)は次のように計算される。この損失関数では、回帰モデルの出力値 f(x) と y の差を 2 乗しているため、両者が離れば離れるほど大きなペナルティを受ける。データに外れ値が含まれると、その外れ値による影響を大きく受ける。 絶対値誤差 データセット (x, y) が与えられたとき、機械学習で得られた回帰モデルの関数を f としたとき、損失関数(絶対値誤差)は次のように計算される。絶対値誤差のペナルティは、二乗誤差のように誤差を 2 乗していないため、二乗誤差に比べてゆっくりと大きくなる。 ニューラルネットワーク 誤差逆伝搬法 ニューラルネットワークで、モデルの予測結果と実際の正解値との誤差をネットワークに逆向きにフィードバックさせてネットワークの重みを更新 問題点 ネットワークが深くなっていくにあたって誤差が最後まで反映されない シグモイド関数が活性化関数として使用されていたが、シグモイド関数の微分は最大値が0.25にしかならない。つうまり、隠れ層を遡るごとに、伝搬していく誤差はどんどん小さくなっていく。深ければ深いほどフィードバックすべき誤差が少ない(匂配消失問題) ディープラーニングのアプローチ 事前学習によるアプローチ オートエンコーダ 可視層と隠れ層の2層からなるネットワーク。可視層は入力層と出力層がセットになったもの。 下記のように入力層と出力層は同じ結果となる。 出力層=入力層>隠れ層とする。隠れ層には圧縮された情報が伝達される。 入力層→隠れ層の処理をエンコード。隠れ層→出力層をデコード オートコーダは入力=出力なのでこの場合はラベルが出力できない。教師なし学習となる。オートエンコーダを積み重ねた最後にロジスティック回帰層(シグモイド関数、ソフトマックス関数による出力層)を足すことで教師あり学習となる ロジスティック回帰層も重みの調整が必要(=ファインチューニング)と言う オートエンコーダは事前学習とファインチューニングの工程で構成 ニューラルネットワークの種類 畳み込みニューラルネットワーク 画像認識 再帰的ニューラルネットワーク(Recurrent Neural Network) 時系列 時間と共に次々と入ってくる、長さも決まらないデータを処理するのに向く イテレーション:すべての学習データ何度も繰り返すこと。訓練誤差を小さくしていく。 バッチ学習:1度にすべての学習データを読み込み ミニバッチ学習:指定した数のデータを学習する オンライン学習:1回の学習で1つのデータのみを読み込む ハイパーパラメータ バッチサイズ ミニバッチ勾配降下法というバッチ勾配降下法と確率的勾配降下法の間を取った手法が使われ、データセットを幾つかのサブセットに分ける この幾つかに分けたぞれぞれのサブセットに含まれるデータの数をバッチサイズ エポック数 データセットをバッチサイズに従ってN個のサブセットに分ける。 各サブセットを学習に回す。つまり、N回学習を繰り返す。 この手順によりデータセットに含まれるデータは少なくとも1度は学習に使用される。エポック数はこの何度繰り返すかのパラメータ 学習率 各層の重みを一度にどの程度変更するかを決めるハイパーパラメータ アルゴリズム Linear Learner 分類・回帰 Factorization Machines 分類・回帰 XGBoost Algorithm 分類・回帰 XGBoostアルゴリズムは、回帰、分類、およびランク付けの問題を解決するために使用 XGBoostは、学習器として回帰木を使い、Boostingによってモデルの構築と学習を行い、学習時にはモデルの勾配情報でパラメータを更新するモデル Image Classification Algorithm 画像分類 Object Detection Algorithm 物体検出 Sequence2Sequence 機械翻訳・テキスト要約・音声認識 K-Means Algorithm クラスタリング グループのメンバーが互いに類似しているが、他のグループのメンバーと異なるデータ内のグループを見つける Principal Component Analysis (PCA) 特徴量の抽出 Latent Dirichlet Allocation (LDA) トピックモデリング 文書中の単語の「トピック」を確率的に求める言語モデル。単語は独立に存在しているのではなく、潜在的なトピックを持ち、同じトピックを持つ単語は同じ文章に出現しやすい。 Neural Topic Model (NTM) トピックモデリング DeepAR Forecasting 時系列データに対する予測 一連の断面単位にわたって多くの同様の時系列を使用して予測しようとする場合に最適に機能。 多くのインプットがあり、いくつかの時系列があり、これらすべての時系列を使用して単一のモデルをトレーニングするために使用可能 ARIMAモデル 1つの時系列を使用してモデルをトレーニング BlazingText Word2Vec Random Cut Forest 異常検知 K-Nearest Neighbors 分類・回帰 tf-idf ドキュメント内で一般的及び一般的ではない単語に重みを付けることにより、ドキュメント内の単語の重要性を決定する Bag-of-Words 入力ドキュメントテキストのトークンを作成し、テキストの統計的描写を出力する IP Insights Object2Vec 「Object2Vec」とは「高次元のベクトルを、できるだけ情報量を減らさずに次元削減し、類似した物体を近距離に配置する」手法であり、汎用的なアルゴリズムです。 「物事の関係性を計算」する Senabtuc Segnebtatuib ​ 自動モデル調整 混同行列 2値分類問題で出力されたクラス分類の結果をまとめたマトリックス(行列≒表)のことで、2値分類機械学習モデルの性能を測る指標 混同行列(Confusion Matrix) とは 〜 2 値分類の機械学習のクラス分類について - Qiita https://qiita.com/TsutomuNakamura/items/a1a6a02cb9bb0dcbb37f 分類における評価法(TN、FN、TP、FP) F1 F1スコア(Fスコア または Fメジャー)は、テストの精度の尺度 その他 文字を整数値に変換して機会学習の対象とする 順序、またはワンホットエンコーディング Sagemakerの自動パラメータチューニング 通常、1度に一つのトレーニングジョブを実行すると最小の計算時間で最良の結果が得られる 不正アルゴリズム 参考サイト、書籍: 損失関数 | 機械学習の学習アルゴリズムの精度を評価する方法について https://axa.biopapyrus.jp/machine-learning/model-evaluation/loss-function.html 深層学習教科書 ディープラーニング G検定(ジェネラリスト) 公式テキスト | 浅川 伸一, 江間 有沙, 工藤 郁子, 巣籠 悠輔, 瀬谷 啓介, 松井 孝之, 松尾 豊, 一般社団法人日本ディープラーニング協会 | コンピュータ・IT | 本 | Amazon https://www.amazon.co.jp/dp/B07H2ZR6M2 エンジニアなら知っておきたいAIのキホン 機械学習・統計学・アルゴリズムをやさしく解説 | 梅田 弘之 | コンピュータサイエンス | Kindleストア | Amazon https://www.amazon.co.jp/dp/B07N1GWYMT --- ### log_fdw拡張機能を使用してAurora PostgreSQLのログを分析する date: 2020-12-08 url: https://zatoima.github.io/aws-aurora-postgresql-log_fdw-analyze-postgreslog.html tags: AWS, Aurora, PostgreSQL PostgreSQLのログをSQLベースで分析出来たら良いなって思ったのが始まり。調べて見ると便利な拡張機能があったのでメモ。 拡張機能の有効化 CREATE EXTENSION log_fdw; 外部データラッパーとしてログサーバーを作成 CREATE SERVER log_server FOREIGN DATA WRAPPER log_fdw; ログファイルのリストを取得 SELECT * from list_postgres_log_files() order by 1; SELECT * FROM list_postgres_log_files() WHERE file_name LIKE 'postgresql.log.%.csv' ORDER BY 1 DESC; ログをインプットにテーブルを作成 SELECT create_foreign_table_for_log_file('postgresql_log_20201206', 'log_server', 'postgresql.log.2020-12-06.csv'); 作成される外部テーブルと各カラムに入るサンプルデータ カラム例 サンプル例 log_time 2020-12-06 09:02:55.872+00 user_name postgres database_name postgres process_id 32418 connection_from 10-0-1-123 session_id 5fcc9e3f.7ea2 session_line_num 2 command_tag authentication session_start_time 2020-12-06 09:02:55+00 virtual_transaction_id 8/65 transaction_id 0 error_severity FATAL sql_state_code 28P01 message password authentication failed for user “postgres” detail Password does not match for user “postgres”. hint internal_query internal_query_pos context query query_pos location application_name ログの中身を確認 select * from postgresql_log_20201206; 特定サーバからログイン失敗した回数を確認 select count(*) from postgresql_log_20201206 where connection_from like '10.0.1.123%' and message like '%password authentication failed %'; 不要になった外部テーブルを削除 DROP FOREIGN TABLE postgresql_log_20201206; 参考 https://aws.amazon.com/jp/blogs/news/working-with-rds-and-aurora-postgresql-logs-part-2/ log_fdw を使用して外部テーブル経由でログデータを表示する --- ### Aurora PostgreSQLのpg_dump、pg_restore目安時間 date: 2020-11-30 url: https://zatoima.github.io/aws-aurora-postgresql-pg_dump_pg_restore_time.html tags: AWS, Aurora, PostgreSQL" EC2上の踏み台サーバに対して、Aurora PostgreSQLのデータをpg_dumpして、pg_restoreする時間を計測してみた。インスタンスタイプやディスクサイズ、IOPS指定により、ネットワーク帯域やディスクのIO性能も変わってくるので目安程度に。 結果 No 検証パターン DB名 DBサイズ(GB) データの中身 開始時間 終了時間 所要時間 1 pg_dump postgres 729GB 青空文庫のテキストデータ 14:31:33 19:01:44 4:30:11 2 ※並列度1で実施 tpch 45GB HammerDBのtpc-hのデータ 12:59:44 13:34:22 0:34:38 3 tpcc 118GB HammerDBのtpc-cのデータ 13:43:07 14:26:32 0:43:25 4 blob 98GB byteaにバイナリ(25MBファイル×4000ファイル) 9:26:14 12:38:51 3:12:37 5 pg_dump postgres 729GB 同上 18:30:26 19:59:33 1:29:07 6 ※並列度8で実施 tpch 45GB 同上 18:11:08 18:28:35 0:17:27 7 tpcc 118GB 同上 13:16:13 13:44:05 0:27:52 8 blob 98GB 同上 20:01:51 21:04:38 1:02:47 9 pg_restore postgres 729GB 同上 21:09:34 0:26:25 3:16:51 10 ※並列度8で実施 tpch 45GB 同上 20:58:25 21:06:24 0:07:59 11 tpcc 118GB 同上 20:46:58 20:56:44 0:09:46 12 blob 98GB 同上 12:45:23 13:07:43 0:22:20 並列度1のpg_dumpコマンド pg_dump -h aurorapgsqlv1.cluster-xxxx.ap-northeast-1.rds.amazonaws.com -U postgres -Fc postgres > postgres.dump 並列度8のpg_dumpコマンド pg_dump -h aurorapgsqlv1.cluster-xxxxx.ap-northeast-1.rds.amazonaws.com -j 8 -U postgres -F d -f /data/postgres postgres 並列度8のpg_restoreコマンド pg_restore -h aurorapgsqlv1.cluster-xxxxx.ap-northeast-1.rds.amazonaws.com -U postgres -j 8 -d postgres postgres.dump --- ### ElastiCacheのRedisにベンチマークを実施する date: 2020-11-27 url: https://zatoima.github.io/aws-elasticache-redis-benchmark.html tags: AWS, ElastiCache, Redis デフォルトで付属されるredis-benchmarkを使用してElastiCacheのRedisに対してベンチマークをしてみる。 マニュアル How fast is Redis? – Redis https://redis.io/topics/benchmarks オプション説明 オプション オプション補足 デフォルト値 説明 -h 127.0.0.1 サーバーのホスト名を指定 -p 6379 サーバポートを指定 -s サーバソケットを指定 -c 50 同時接続数を指定 -n 100000 リクエストの数を指定 -d 2 データサイズのバイトの形式でSET / GETの値を指定 -r 実際のオペレーションを想定してランダムなコマンドを発行して、キャッシュミスを誘発する例:100kの可能なキーのうちすべての操作にランダムキーを使用して100万のSET操作を実行するredis-benchmark -t set -r 100000 -n 1000000 -k 1 1=keep alive 0=reconnect -P 1 パイプラインを有効化https://redis.io/topics/pipelining -q クエリ/秒の値のみを表示 -csv CSV形式で出力。ヘッダーは出力されないので注意 -l ひたすらループ処理 -t カンマで区切られたテストのリストのみを実行 例: -t get,set → get と setコマンドのみ実行 -I アイドルモード パターン1 デフォルト設定で実施。リクエスト数「100,000」、同時接続数「50」、データサイズ「2バイト」等 redis-benchmark -h redistest.xxxxx.0001.apne1.cache.amazonaws.com 出力結果 レイテンシのばらつきやレクエストが何秒で完了したか出力 [ec2-user@bastin ~]$ redis-benchmark -h redistest.xxxxx.0001.apne1.cache.amazonaws.com ====== PING_INLINE ====== 100000 requests completed in 2.62 seconds 50 parallel clients 3 bytes payload keep alive: 1 12.45% <= 1 milliseconds 98.95% <= 2 milliseconds 99.54% <= 3 milliseconds 99.75% <= 4 milliseconds 99.90% <= 5 milliseconds 99.97% <= 6 milliseconds 100.00% <= 6 milliseconds 38138.82 requests per second ~省略~ パターン2 サイレントモードで実施する。クエリ/秒の値のみを表示。 redis-benchmark -h redistest.xxxxx.0001.apne1.cache.amazonaws.com -q 出力結果 [ec2-user@bastin ~]$ redis-benchmark -h redistest.xxxxx.0001.apne1.cache.amazonaws.com -q PING_INLINE: 43840.42 requests per second PING_BULK: 35958.29 requests per second SET: 37907.50 requests per second GET: 34293.55 requests per second INCR: 41288.19 requests per second LPUSH: 43327.55 requests per second RPUSH: 43725.41 requests per second LPOP: 46403.71 requests per second RPOP: 44943.82 requests per second SADD: 45085.66 requests per second HSET: 27563.40 requests per second SPOP: 34258.31 requests per second LPUSH (needed to benchmark LRANGE): 31279.32 requests per second LRANGE_100 (first 100 elements): 30902.35 requests per second LRANGE_300 (first 300 elements): 15941.34 requests per second LRANGE_500 (first 450 elements): 12241.40 requests per second LRANGE_600 (first 600 elements): 9856.10 requests per second MSET (10 keys): 25766.55 requests per second パターン3 クライアント数を「100」に増やし、かつ「set」と「get」コマンドのみ実行する。(サイレントモード) redis-benchmark -h redistest.xxxxx.0001.apne1.cache.amazonaws.com -p 6379 -c 100 -n 100000 -q -t set,get 出力結果 [ec2-user@bastin ~]$ redis-benchmark -h redistest.xxxxx.0001.apne1.cache.amazonaws.com -p 6379 -c 100 -n 100000 -q -t set,get SET: 45766.59 requests per second GET: 42789.90 requests per second パターン4 CSVモードで実行 redis-benchmark -h redistest.xxxxx.0001.apne1.cache.amazonaws.com -p 6379 -c 100 -n 100000 -t set,get --csv 出力結果 [ec2-user@bastin ~]$ redis-benchmark -h redistest.xxxxx.0001.apne1.cache.amazonaws.com -p 6379 -c 100 -n 100000 -t set,get --csv "SET","41562.76" "GET","38491.14" その他 redis-cli に--latencyを付与することでPINGを使用したレイテンシを計測することが出来る。ひたすらサンプルを取り続けるのでCtrl+Cでストップする [ec2-user@bastin ~]$ redis-cli -h redistest.xxxx.0001.apne1.cache.amazonaws.com -p 6379 --latency min: 0, max: 18, avg: 0.40 (4591 samples) --- ### PostgreSQLでpg_dumpした場合の圧縮率 date: 2020-11-26 url: https://zatoima.github.io/aws-postgresql-pg_dump_zip.html tags: PostgreSQL 表題の件を検証。カスタムファイル(圧縮)で出力されるよう-Fcオプションを付与。こんな感じになりました。int、string主体だと圧縮率は高め。 No 検証パターン DB名 DBサイズ(GB) データの中身 ダンプファイルの容量(GB) 圧縮率 1 pg_dump postgres 729GB 青空文庫のテキストデータ 66 9% 2 tpch 45GB HammerDBのtpc-hのデータ 9.9 22% 3 tpcc 118GB HammerDBのtpc-cのデータ 34 29% 4 blob 98GB byteaにバイナリ(25MBファイル×4000ファイル) 108 110% --- ### Aurora PostgreSQLの拡張機能のpgauditで特定ユーザのみの監査を設定する date: 2020-11-20 url: https://zatoima.github.io/aws-aurora-postgresql-pgaudit-user.html tags: AWS, Aurora, PostgreSQL, pgaudit パラメータグループの有効化 DB インスタンスに関連付けられているパラメータグループを変更し、pgaudit が含まれている共有事前ロードライブラリを使用して、パラメータ pgaudit.role を設定して、pgaudit.role はロール rds_pgaudit に設定する必要がある。この時、pgaudit.log パラメータの値にデータベース、ロール、またはテーブルを設定するために、パラメータグループレベルでは pgaudit.log パラメータを none に設定。 rds_pgaudit という専用のデータベースロールを作成 postgres=> CREATE ROLE rds_pgaudit; CREATE ROLE pgaudit 拡張機能を有効化 CREATE EXTENSION pgaudit; 設定値確認 postgres=> show shared_preload_libraries; shared_preload_libraries ------------------------------------- rdsutils,pg_stat_statements,pgaudit (1 row) postgres=> show pgaudit.role; pgaudit.role -------------- rds_pgaudit (1 row) postgres=> show pgaudit.log; pgaudit.log ------------- none (1 row) 監査対象のサンプルDBの作成 postgres=> create database auditdb WITH OWNER postgres; CREATE DATABASE DB接続先の切替 postgres=> \c auditdb psql (11.5, server 11.7) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) You are now connected to database "auditdb" as user "postgres". ユーザ作成 auditdb=> CREATE ROLE audit_user1 WITH CREATEDB CREATEROLE LOGIN PASSWORD 'xxxxxx'; CREATE ROLE auditdb=> CREATE ROLE audit_user2 WITH CREATEDB CREATEROLE LOGIN PASSWORD 'xxxxxx'; CREATE ROLE ユーザの監査設定の変更 audit_user1ユーザのみすべての操作の監査を行う設定に。 auditdb=> ALTER ROLE audit_user1 set pgaudit.log='All'; ALTER ROLE auditdb=> ALTER ROLE audit_user2 set pgaudit.log='NONE'; ALTER ROLE ユーザの監査設定の確認 auditdb=> select rolname,rolconfig from pg_roles where rolname in ('postgres','audit_user1','audit_user2'); rolname | rolconfig -------------+-------------------- audit_user1 | {pgaudit.log=All} audit_user2 | {pgaudit.log=NONE} postgres | (3 rows) 監査設定済のaudit_user1でDDL/DMLを実行 auditdb=> \c - audit_user1; psql (11.5, server 11.7) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) You are now connected to database "auditdb" as user "audit_user1". auditdb=> auditdb=> auditdb=> auditdb=> auditdb=> CREATE TABLE t1 AS auditdb-> SELECT num a -- 生成値 auditdb-> ,'1' b -- 定数 auditdb-> ,to_char(num,'FM00000') c -- 生成値を利用(IDなどの文字列) auditdb-> ,current_timestamp d auditdb-> FROM generate_series(1,10000000) num auditdb-> ; SELECT 10000000 auditdb=> auditdb=> select count(*) from t1; count ---------- 10000000 (1 row) auditdb=> ログ出力を確認 2020-11-13 08:06:24 UTC:10.0.1.123(50322):audit_user1@auditdb:[24298]:LOG: AUDIT: SESSION,1,2,DDL,CREATE TABLE AS,,,"CREATE TABLE t1 AS SELECT num a ,'1' b ,to_char(num,'FM00000') c ,current_timestamp d FROM generate_series(1,10000000) num ;",<none> 2020-11-13 08:07:36 UTC:10.0.1.123(50322):audit_user1@auditdb:[24298]:LOG: AUDIT: SESSION,2,1,READ,SELECT,TABLE,public.t1,select count(*) from t1;,<none> 2020-11-13 08:07:36 UTC::@:[32064]:LOG: AUDIT: SESSION,1,1,READ,SELECT,TABLE,public.t1,select count(*) from t1;,<none> 監査設定を行っていないaudit_user2でDDL/DMLを実行 auditdb=> \c - audit_user2; psql (11.5, server 11.7) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) You are now connected to database "auditdb" as user "audit_user2". auditdb=> auditdb=> auditdb=> auditdb=> CREATE TABLE t2 AS auditdb-> SELECT num a -- 生成値 auditdb-> ,'1' b -- 定数 auditdb-> ,to_char(num,'FM00000') c -- 生成値を利用(IDなどの文字列) auditdb-> ,current_timestamp d auditdb-> FROM generate_series(1,100000) num auditdb-> ; SELECT 100000 auditdb=> select count(*) from t2; count -------- 100000 (1 row) auditdb=> ログ出力を確認 特にaudit_user2の操作のログは出力されていない。 2020-11-13 08:06:24 UTC:10.0.1.123(50322):audit_user1@auditdb:[24298]:LOG: AUDIT: SESSION,1,2,DDL,CREATE TABLE AS,,,"CREATE TABLE t1 AS SELECT num a ,'1' b ,to_char(num,'FM00000') c ,current_timestamp d FROM generate_series(1,10000000) num ;",<none> 2020-11-13 08:07:36 UTC:10.0.1.123(50322):audit_user1@auditdb:[24298]:LOG: AUDIT: SESSION,2,1,READ,SELECT,TABLE,public.t1,select count(*) from t1;,<none> 2020-11-13 08:07:36 UTC::@:[32064]:LOG: AUDIT: SESSION,1,1,READ,SELECT,TABLE,public.t1,select count(*) from t1;,<none> 参考 pgaudit 拡張機能を使用して、 PostgreSQL を実行する Amazon RDS DB インスタンスを監査する https://aws.amazon.com/jp/premiumsupport/knowledge-center/rds-postgresql-pgaudit/ pgAudit Open Source PostgreSQL Audit Logging https://github.com/pgaudit/pgaudit --- ### Amazon EC2上でPython + Seleniumを実行するまで date: 2020-11-16 url: https://zatoima.github.io/aws-ec2-python-selenium-install.html tags: AWS, EC2, Python, Selenium 少しハマってしまったので、いつの日にか再度実施することを考慮してメモ。 事前準備 python3とSeleniumをインストール sudo yum install python3 sudo pip3 install Selenium Chromeをインストールする sudo yum -y install https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm stable版をインストールしたらバージョン**86.0**が入った模様。 [ec2-user@bastin py]$ rpm -qa | grep google-chrome google-chrome-stable-86.0.4240.198-1.x86_64 ChromeDriverをインストール 下記のサイトからgoogle-chromeをインストールした際のバージョンに合うChromeを選択する Downloads - ChromeDriver - WebDriver for Chrome https://chromedriver.chromium.org/downloads バージョンが合わないと下記のようなエラーが発生する [ec2-user@bastin py]$ python3 test_selenium.py Traceback (most recent call last): File "test_selenium.py", line 21, in <module> _main() File "test_selenium.py", line 8, in _main driver = webdriver.Chrome(options=options) File "/usr/local/lib/python3.7/site-packages/selenium/webdriver/chrome/webdriver.py", line 81, in __init__ desired_capabilities=desired_capabilities) File "/usr/local/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 157, in __init__ self.start_session(capabilities, browser_profile) File "/usr/local/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 252, in start_session response = self.execute(Command.NEW_SESSION, parameters) File "/usr/local/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute self.error_handler.check_response(response) File "/usr/local/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response raise exception_class(message, screen, stacktrace) selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 87 Current browser version is 86.0.4240.198 with binary path /usr/bin/google-chrome headlessモードでseleniumを実行可能となる。 --- ### Aurora PostgreSQLにHammerDBのTPC-Cを実行 date: 2020-11-13 url: https://zatoima.github.io/aws-aurora-postgresql-hammerdb-benchmark.html tags: AWS, Aurora, PostgreSQL Auroraを対象にHammerDBのTPC-Cを使ってみましたが、(当然ですが、)ほぼ普通のPostgreSQL と同じ手順。 はじめに CLI実行とのことで、下記のHammerDBのドキュメントを参考 Chapter 8. Command Line Interface (CLI) https://hammerdb.com/docs/ch08.html 事前準備 PostgreSQL関連のライブラリが既にインストールされていることを前提。無ければ下記でインストールしておく。 sudo yum -y install postgresql sudo yum -y install postgresql-contrib HammerDBのインストーラーダウンロード wget https://github.com/TPC-Council/HammerDB/releases/download/v3.3/HammerDB-3.3-Linux.tar.gz tar xvzf HammerDB-3.3-Linux.tar.gz cd HammerDB-3.3 HammerDB https://hammerdb.com/download.html ライブラリ確認 PostgreSQLのライブラリのチェックのSuccessを確認する。 Checking database library for PostgreSQL Success ... loaded library Pgtcl for PostgreSQL [ec2-user@bastin HammerDB-3.3]$ ls -l total 100 drwxr-xr-x 2 ec2-user ec2-user 19 Oct 18 2019 agent drwxr-xr-x 2 ec2-user ec2-user 37 Oct 21 2019 bin -rwxr-xr-x 1 ec2-user ec2-user 29218 Oct 16 2019 ChangeLog drwxr-xr-x 2 ec2-user ec2-user 178 Oct 16 2019 config -rwxr-xr-x 1 ec2-user ec2-user 7274 Oct 16 2019 hammerdb -rwxr-xr-x 1 ec2-user ec2-user 3167 Oct 16 2019 hammerdbcli -rwxr-xr-x 1 ec2-user ec2-user 2508 Oct 16 2019 hammerdbws drwxr-xr-x 2 ec2-user ec2-user 39 Jul 19 2019 images drwxr-xr-x 2 ec2-user ec2-user 4096 Oct 21 2019 include drwxr-xr-x 21 ec2-user ec2-user 4096 Oct 21 2019 lib -rwxr-xr-x 1 ec2-user ec2-user 34666 Jul 19 2019 license drwxr-xr-x 2 ec2-user ec2-user 4096 Oct 16 2019 modules -rwxr-xr-x 1 ec2-user ec2-user 116 Oct 16 2019 readme drwxr-xr-x 10 ec2-user ec2-user 126 Jul 19 2019 src [ec2-user@bastin HammerDB-3.3]$ ./hammerdbcli HammerDB CLI v3.3 Copyright (C) 2003-2019 Steve Shaw Type "help" for a list of commands The xml is well-formed, applying configuration hammerdb>librarycheck Checking database library for Oracle Error: failed to load Oratcl - can't read "env(ORACLE_HOME)": no such variable Ensure that Oracle client libraries are installed and the location in the LD_LIBRARY_PATH environment variable Checking database library for MSSQLServer Error: failed to load tdbc::odbc - couldn't load file "libiodbc.so": libiodbc.so: cannot open shared object file: No such file or directory Ensure that MSSQLServer client libraries are installed and the location in the LD_LIBRARY_PATH environment variable Checking database library for Db2 Error: failed to load db2tcl - couldn't load file "/home/ec2-user/HammerDB-3.3/lib/db2tcl2.0.0/libdb2tcl.so.0.0.1": libdb2.so.1: cannot open shared object file: No such file or directory Ensure that Db2 client libraries are installed and the location in the LD_LIBRARY_PATH environment variable Checking database library for MySQL Error: failed to load mysqltcl - couldn't load file "/home/ec2-user/HammerDB-3.3/lib/mysqltcl-3.052/libmysqltcl3.052.so": libmysqlclient.so.21: cannot open shared object file: No such file or directory Ensure that MySQL client libraries are installed and the location in the LD_LIBRARY_PATH environment variable Checking database library for PostgreSQL Success ... loaded library Pgtcl for PostgreSQL Checking database library for Redis Success ... loaded library redis for Redis HammerDBのパラメータ設定 接続DBをPostgreSQL 指定 hammerdb> dbset db pg 対象ベンチマークをTPC-Cに設定する hammerdb> dbset bm TPC-C 接続先ホスト名の設定 hammerdb> diset connection pg_host aurorapgsqlv1.cluster-xxxxxxxxx.ap-northeast-1.rds.amazonaws.com superuserのユーザ名、パスワードの設定 hammerdb> diset tpcc pg_superuser postgres hammerdb> diset tpcc pg_superuserpass postgres pg_driverの変更 環境整整備、動作検証までは「test」を、実計測時は「timed」を指定 hammerdb> diset tpcc pg_driver timed pg_timeprofileの変更 trueにすると、10秒間隔での応答時間のパーセンタイル、完了時の累積値がレポート hammerdb> diset tpcc pg_timeprofile true pg_total_iterationsの変更 トランザクションの実行回数を指定(デフォルト 1000000) hammerdb> diset tpcc pg_total_iterations 100000 pg_count_ware(スケールファクター)の設定 データ容量を調整する。 hammerdb> diset tpcc pg_count_ware 10 pg_num_vu(同時実行ユーザ)の設定 データ容量を調整する。 hammerdb> diset tpcc pg_num_vu 4 設定値を確認 hammerdb> print dict hammerdb>print dict Dictionary Settings for PostgreSQL connection { pg_host = aurorapgsqlv1.cluster-xxxxxxxxx.ap-northeast-1.rds.amazonaws.com pg_port = 5432 } tpcc { pg_count_ware = 10 pg_num_vu = 1 pg_superuser = postgres pg_superuserpass = postgres pg_defaultdbase = postgres pg_user = tpcc pg_pass = tpcc pg_dbase = tpcc pg_vacuum = false pg_dritasnap = false pg_oracompat = false pg_storedprocs = false pg_total_iterations = 100000 pg_raiseerror = false pg_keyandthink = false pg_driver = timed pg_rampup = 2 pg_duration = 5 pg_allwarehouse = false pg_timeprofile = true pg_async_scale = false pg_async_client = 10 pg_async_verbose = false pg_async_delay = 1000 } スキーマ作成 スキーマ作成、及び、テストデータの投入 データロードが走るので時間が掛かる。 hammerdb>buildschema Script cleared Building 1 Warehouses(s) with 1 Virtual User Ready to create a 1 Warehouse PostgreSQL TPC-C schema in host xxxxxx.CLUSTER-xxxxxxxx.AP-NORTHEAST-1.RDS.AMAZONAWS.COM:5432 under user TPCC in database TPCC? Enter yes or no: replied yes Vuser 1 created - WAIT IDLE RUNNING - TPC-C creation Vuser 1:RUNNING Vuser 1:CREATING TPCC SCHEMA Vuser 1:CREATING DATABASE tpcc under OWNER tpcc ~省略~ Vuser 1:GATHERING SCHEMA STATISTICS Vuser 1:TPCC SCHEMA COMPLETE Vuser 1:FINISHED SUCCESS ALL VIRTUAL USERS COMPLETE TPC-C Driver Script hammerdb> スケールファクタを10倍に設定して、完了後にPostgreSQL側のtpccデータベースにログインして確認すれば9つのテーブルが作成されていることがわかる。 postgres@aurorapgsqlv1:tpcc> \dt+ +----------+------------+--------+---------+---------+---------------+ | Schema | Name | Type | Owner | Size | Description | |----------+------------+--------+---------+---------+---------------| | public | customer | table | tpcc | 371 MB | <null> | | public | district | table | tpcc | 168 kB | <null> | | public | history | table | tpcc | 56 MB | <null> | | public | item | table | tpcc | 21 MB | <null> | | public | new_order | table | tpcc | 7864 kB | <null> | | public | order_line | table | tpcc | 656 MB | <null> | | public | orders | table | tpcc | 43 MB | <null> | | public | stock | table | tpcc | 710 MB | <null> | | public | warehouse | table | tpcc | 40 kB | <null> | +----------+------------+--------+---------+---------+---------------+ SELECT 9 Time: 0.021s ロード用のクライアントプロセスをkillする hammerdb>vudestroy Destroying Virtual Users Virtual Users Destroyed vudestroy success スクリプトのロード hammerdb>loadscript TPC-C Driver Script Script loaded, Type "print script" to view テスト実行用クライアント(Virtual User)の設定、作成 hammerdb>vuset vu 4 hammerdb>vuset logtotemp 1 hammerdb>vuset showoutput 1 hammerdb>vuset unique 1 hammerdb>vuset timestamps 1 hammerdb>print vuconf Virtual Users = 4 User Delay(ms) = 500 Repeat Delay(ms) = 500 Iterations = 1 Show Output = 1 Log Output = 1 Unique Log Name = 1 No Log Buffer = 0 Log Timestamps = 1 hammerdb> hammerdb> vucreate Vuser 1 created MONITOR - WAIT IDLE Vuser 2 created - WAIT IDLE Vuser 3 created - WAIT IDLE Vuser 4 created - WAIT IDLE Vuser 5 created - WAIT IDLE Logging activated to /tmp/hammerdb_5FADF0FE5B3F03E293835333.log 5 Virtual Users Created with Monitor VU hammerdb>vustatus 1 = WAIT IDLE 2 = WAIT IDLE 3 = WAIT IDLE 4 = WAIT IDLE 5 = WAIT IDLE HammerDBの実行 hammerdb> vurun 実行結果 ~省略~ Vuser 1:TEST RESULT : System achieved 14999 PostgreSQL TPM at 6461 NOPM ~省略~ TPM = Transactions Per Minute=トランザクション数/分 NOPM = New Order Per Minute=TPC-Cのシナリオにおける新規オーダー(注文)数/分 クリーンアップ hammerdb>vucomplete true hammerdb>vudestroy Destroying Virtual Users Virtual Users Destroyed vudestroy success hammerdb>clearscript Script cleared 参考 HammerDBを使用してPostgreSQLのベンチマークを実施する - Qiita https://qiita.com/mkyz08/items/a9f224dbf4ea7b83e2e9 HammerDBをCLIで使うなど(3):PostgreSQLにTPC-Cを実行してみる - なからなLife https://atsuizo.hatenadiary.jp/entry/2019/08/28/090000 --- ### BYOKでインポートしたKMSキーの注意事項、考慮事項 date: 2020-10-30 url: https://zatoima.github.io/aws-kms-import-key.html tags: AWS, KMS BYOK実施時の注意点、考慮点 --- ### AWS認定データベース – 専門知識(DBS-C01)の合格体験記 date: 2020-10-28 url: https://zatoima.github.io/aws-certified-database-specialty.html tags: AWS 結構前ですが、AWS認定データベース – 専門知識(AWS Certified Database - Specialty) に合格しました。データベースのお仕事が多いので、こういった資格で知識やスキルの裏付け出来るのは大変嬉しいです。これでデータベースの資格はOracle Master Gold、OSS-DB Goldと合わせて3種類となりました。 この資格が2020年5月にリリースされてまだそこまで月日が経っておらず、当時のメモをブログ公開していなかったので、これから受ける方たちの参考になればと思い私の勉強方法を書いておきます。 試験の概要 https://aws.amazon.com/jp/certification/certified-database-specialty/ 時間:180分 問題数:65問 合格点:75%以上 勉強方法 1.まずは最初の第一歩で試験ガイドを流し読む https://d1.awsstatic.com/ja_JP/training-and-certification/docs-database-specialty/AWS-Certified-Database-Specialty_Exam-Guide.pdf 2.下記サービスのBlackBelt資料を読み込む。 PDF資料を読むよりも、Youtubeの字幕あり、速度2倍をオススメします。目と耳で頭に入れた方が定着度があるような気が 重要高 Relational Database Service (RDS) Aurora with MySQL Compatibility Aurora with PostgreSQL Compatibility DynamoDB CloudFormation Key Management Service 重要度中~低 ElastiCache DocumentDB Neptune Redshift 3.AWS Certified Database - Specialtyの試験対策のE-Learningが無料で受講可 試験ガイドに記載されているセクションごとに講義が用意されています。 https://www.aws.training/Details/eLearning?id=47245 4.問題傾向を把握 https://devopspages.io/aws-certified-database-specialty-exam-guide/ http://drawing-hisa.seesaa.net/article/473054025.html 5.実機で触りまくる Aurora、RDS、DynamoDBの機能についてはマニュアルをベースにほとんど触りました。Aurora グローバルデータベース、Aurora Serverless、Aurora クローニング、監査…こんな機能実際にはまだ使わないのでは?というのも出題されますのでこちらのサービスに関しては重点的にやった方が良い気がします 6. 有料問題集を購入して解く 私はこちらの問題集を解きました。試験問題や傾向に慣れる上で良かったかな、と思います。ちょっとDynamoDBの問題数が多いかな、と思いましたが。 https://www.whizlabs.com/learn/course/aws-certified-database-specialty/ 7.模擬試験を解く この試験には模擬試験も用意されているので受験前の総チェックとして受験してみました。私は受験前に60%の得点率でこれはやばい!と思っていました。 出題傾向 私が受験した時の出題傾向は体感的にこんな感じでした No サービス 配分 1 RDS/Aurora 40% 2 DynamoDB 15% 3 DMS/SCT 15% 4 Key Management Service 5% 5 Redshift 5% 5 トラブルシューティング 5% 6 その他 15% 最後に 今回が初めてのAWSの専門資格系(Specialty)の取得だったので取得出来た時は凄く嬉しかったです。ただ、そこまで難しいとは思えず、このSpecialty資格を取ったからと言って専門性の証明になるわけではなく、この分野の一通りの知識を持っています、という程度なのかな、と思いました。資格はその分野の第一歩に過ぎないみたいなことを誰かが言っていてそのとおりだな、と。 --- ### pythonの画像処理ライブラリPillow(PIL)を使用して対象ディレクトリ配下の画像ファイル一式に枠を付ける date: 2020-10-26 url: https://zatoima.github.io/python-pillow-pic-frame.html tags: Python Pythonスクリプト実行時に、対象ディレクトリを入力して、その配下のディレクトリに配置されている画像ファイル一式(png、jpeg)の外枠をグレーの枠を付けるスクリプト。既存のファイル名で再保存するので元の画像ファイルが消えてしまうことに注意。 このブログは背景が白なので、画像が白ベースの場合、どこが境界線か分かりづらく画像が見にくかったので、フレームを付けることにしました。Windows上で実行することを想定。 Pythonスクリプト import os from pathlib import Path from PIL import Image, ImageDraw def main(): pic_flame() def pic_flame(): print('画像を変更したい対象ディレクトリを入力してください') dir_path = input('>> ') #末尾のスラッシュ有無を確認し、スラッシュを付与 if(dir_path[-1:]!="\\"): dir_path=dir_path + '\\' print(dir_path) outline_color = (128, 128, 128) # 枠線の色(R,G,B)で指定 outline_width = 2 #枠線の太さを指定 for f in Path(dir_path).rglob('*'): if Path.is_file(f): try: im = Image.open(f) w, h = im.size draw = ImageDraw.Draw(im) draw.rectangle((0, 0, w-1, h-1), outline = outline_color, width=outline_width) im.save(f) print(f) except: continue if __name__ == '__main__': main() 実行結果 C:\Users\imazaj>python C:\py\pic_flame_v2.py 画像を変更したい対象ディレクトリを入力してください >> C:\hugo\zatoima.github.io\content\post C:\hugo\zatoima.github.io\content\post\ C:\hugo\zatoima.github.io\content\post\2019-06-22-Oracle Database 19cインストール\image-20191121171602652.png C:\hugo\zatoima.github.io\content\post\2019-06-22-Oracle Database 19cインストール\image-20191121171608425.png ~中略~ C:\hugo\zatoima.github.io\content\post\2020-09-04-AWSのドキュメントの更新履歴をgithubで確認する\image-20200903144448386.png C:\hugo\zatoima.github.io\content\post\2020-09-04-AWSのドキュメントの更新履歴をgithubで確認する\image-20200903144451541.png C:\hugo\zatoima.github.io\content\post\2020-09-04-AWSのドキュメントの更新履歴をgithubで確認する\image-20200903144632795.png C:\hugo\zatoima.github.io\content\post\2020-09-04-AWSのドキュメントの更新履歴をgithubで確認する\image-20200903145022613.png C:\hugo\zatoima.github.io\content\post\2020-09-30-EC2のハイパースレッディングを無効化する方法\image-20200919224823587.png 画像の編集結果 --- ### アベイラビリティーゾーンのZoneNameとZoneIdのマッピングを確認する date: 2020-10-22 url: https://zatoima.github.io/aws-availabilityzone-mapping-zonename-zoneid.html tags: AWS アベイラビリティーゾーンには ZoneName と ZoneIdという概念があり、マニュアルに記載がある通り、アカウントごとでは異なるということのメモ。例えば、ap-northeast-1aはZoneIdがapne1-az4のアカウントもあれば、apne1-az1であるアカウントもあるということ。この仕様がないとリソースがap-northeast-1aに集中してしまうことになりそう。 リソースの AZ ID - AWS Resource Access Manager https://docs.aws.amazon.com/ja_jp/ram/latest/userguide/working-with-az-ids.html リソースがリージョンの複数のアベイラビリティーゾーンに分散されるようにするために、アベイラビリティーゾーンは各アカウントの名前に個別にマッピングされます。たとえば、お客様の AWS アカウントのアベイラビリティーゾーン us-east-1a は別の AWS アカウントのアベイラビリティーゾーン us-east-1a と同じ場所にはない可能性があります。 リージョンとゾーン - Amazon Elastic Compute Cloud https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-regions-availability-zones.html アカウント間でアベイラビリティーゾーンを調整するには、アベイラビリティーゾーンの一意で一貫性のある識別子である AZ ID を使用する必要があります。たとえば、use1-az1 は、us-east-1 リージョンの AZ ID で、すべての AWS アカウントで同じ場所になります。 AZ ID を表示すると、アカウント間でリソースの場所を区別できます。たとえば、AZ ID use-az2 のアベイラビリティーゾーンにあるサブネットを別のアカウントと共有する場合、このサブネットは AZ ID が同じく use-az2 であるアベイラビリティーゾーンのそのアカウントでも利用できます。各 VPC とサブネットの AZ ID は Amazon VPC コンソールに表示されます。 このコマンド(aws ec2 describe-availability-zones)で確認することが可能。自アカウントの場合のZoneIDは下記の通りだった。 ZoneName ZoneId ap-northeast-1a apne1-az4 ap-northeast-1c apne1-az1 ap-northeast-1d apne1-az2 [ec2-user@bastin ~]$ aws ec2 describe-availability-zones { "AvailabilityZones": [ { "OptInStatus": "opt-in-not-required", "Messages": [], "ZoneId": "apne1-az4", "GroupName": "ap-northeast-1", "State": "available", "NetworkBorderGroup": "ap-northeast-1", "ZoneName": "ap-northeast-1a", "RegionName": "ap-northeast-1" }, { "OptInStatus": "opt-in-not-required", "Messages": [], "ZoneId": "apne1-az1", "GroupName": "ap-northeast-1", "State": "available", "NetworkBorderGroup": "ap-northeast-1", "ZoneName": "ap-northeast-1c", "RegionName": "ap-northeast-1" }, { "OptInStatus": "opt-in-not-required", "Messages": [], "ZoneId": "apne1-az2", "GroupName": "ap-northeast-1", "State": "available", "NetworkBorderGroup": "ap-northeast-1", "ZoneName": "ap-northeast-1d", "RegionName": "ap-northeast-1" } ] } [ec2-user@bastin ~]$ [ec2-user@bastin ~]$ aws ec2 describe-availability-zones --region ap-northeast-1 | jq -c '.AvailabilityZones[] | {RegionName: .RegionName, ZoneName: .ZoneName, ZoneId: .ZoneId}' {"RegionName":"ap-northeast-1","ZoneName":"ap-northeast-1a","ZoneId":"apne1-az4"} {"RegionName":"ap-northeast-1","ZoneName":"ap-northeast-1c","ZoneId":"apne1-az1"} {"RegionName":"ap-northeast-1","ZoneName":"ap-northeast-1d","ZoneId":"apne1-az2"} [ec2-user@bastin ~]$ --- ### AWS Application Discovery ServiceのエージェントをEC2(Linux)にインストールする date: 2020-10-12 url: https://zatoima.github.io/aws-ec2-application-discovery-service.html tags: AWS, EC2, Migration Hub, AWS Application Discovery Service AWS Application Discovery Serviceとは? https://aws.amazon.com/jp/application-discovery/ AWS Application Discovery Service では、オンプレミスデータセンターに関する情報を収集することにより、エンタープライズのお客様の移行プロジェクト計画を支援しています。 データセンター移行計画には何千ものワークロードが存在し、多くの場合それらが相互に深く依存しあっています。サーバーの使用率データや依存関係のマッピングは、移行プロセス初期の重要なステップです。AWS Application Discovery Service では、サーバーの設定データ、使用状況データ、動作データが収集され、お客様に提供されます。これにより、お客様はワークロードを十分に把握することができます。 収集されたデータは、AWS Application Discovery Service のデータストアに暗号化形式で保存されます。このデータを CSV ファイルとしてエクスポートし、AWS で稼働した場合の総所有コスト (TCO) の見積もりや、AWS への移行計画に使用できます。また、このデータは AWS Migration Hub でも利用できます。このサービスでは、検出したサーバーを AWS に移行し、AWS に移行する際の進捗を追跡できます。 エージェントインストール、情報収集 ということで、VMware vCenter向けのエージェントレス構成ではなく、Linuxにエージェントを導入してどのような情報を取得出来るか見てみる。 前準備 Migration Hubの設定画面でMigration Hubホームリージョンを指定する。 エージェントをダウンロード [ec2-user@bastin ads]$ curl -o ./aws-discovery-agent.tar.gz https://s3-us-west-2.amazonaws.com/aws-discovery-agent.us-west-2/linux/latest/aws-discovery-agent.tar.gz % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 36.6M 100 36.6M 0 0 7330k 0 0:00:05 0:00:05 --:--:-- 8357k [ec2-user@bastin ads]$ ls -l total 37536 -rw-rw-r-- 1 ec2-user ec2-user 38433031 Oct 2 21:16 aws-discovery-agent.tar.gz [ec2-user@bastin ads]$ エージェントの暗号署名を確認 7638 F24C 6717 F97C 4F1B 3BC0 5133 255E 4DF4 2DA2となることを確認 [ec2-user@bastin ads]$ curl -o ./agent.sig https://s3.us-west-2.amazonaws.com/aws-discovery-agent.us-west-2/linux/latest/aws-discovery-agent.tar.gz.sig % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 819 100 819 0 0 1628 0 --:--:-- --:--:-- --:--:-- 1625 [ec2-user@bastin ads]$ [ec2-user@bastin ads]$ curl -o ./discovery.gpg https://s3.us-west-2.amazonaws.com/aws-discovery-agent.us-west-2/linux/latest/discovery.gpg % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 2255 100 2255 0 0 5207 0 --:--:-- --:--:-- --:--:-- 5195 [ec2-user@bastin ads]$ [ec2-user@bastin ads]$ gpg --no-default-keyring --keyring ./discovery.gpg --verify agent.sig aws-discovery-agent.tar.gz gpg: Signature made Fri 18 Sep 2020 07:33:42 AM JST using RSA key ID 4DF42DA2 gpg: directory `/home/ec2-user/.gnupg' created gpg: new configuration file `/home/ec2-user/.gnupg/gpg.conf' created gpg: WARNING: options in `/home/ec2-user/.gnupg/gpg.conf' are not yet active during this run gpg: /home/ec2-user/.gnupg/trustdb.gpg: trustdb created gpg: Good signature from "AWS Application Discovery Service <aws-application-discovery-service@amazon.com>" gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner. Primary key fingerprint: 7638 F24C 6717 F97C 4F1B 3BC0 5133 255E 4DF4 2DA2 [ec2-user@bastin ads]$ エージェントを解凍 [ec2-user@bastin ads]$ tar -xzf aws-discovery-agent.tar.gz [ec2-user@bastin ads]$ ls -l total 75244 -rw-rw-r-- 1 ec2-user ec2-user 819 Oct 2 21:16 agent.sig -rw-r--r-- 1 ec2-user ec2-user 25637518 Sep 3 09:03 aws-discovery-agent.deb -rw-r--r-- 1 ec2-user ec2-user 12934413 Sep 3 09:02 aws-discovery-agent.rpm -rw-rw-r-- 1 ec2-user ec2-user 38433031 Oct 2 21:16 aws-discovery-agent.tar.gz -rw-rw-r-- 1 ec2-user ec2-user 2255 Oct 2 21:16 discovery.gpg -rw-r--r-- 1 ec2-user ec2-user 27548 Sep 3 09:02 install エージェントのインストール aws-access-key-idやaws-secret-access-keyは各自のidとkeyを設定 [ec2-user@bastin ads]$ sudo bash install -r ap-northeast-1 -k xxxxxxxxxxxx -s xxx/xxxxxxxxxxxx+xxxxxxx AWS region option specified as: ap-northeast-1. AWS key ID option specified as: xxxxxxxxxxxxxxx. AWS key secret option specified. ************************************************** INIT PHASE ************************************************** Distribution type of the machine is amzn. Distribution of the machine is Amazon Linux. Revision of the distribution is 2. bastin is using IAM authentication with AWS region ap-northeast-1. There is no existing version of the AWS Discovery Agent on the machine. Using rpm and yum for package management. Expected agent package name is aws-discovery-agent.rpm. Installing using local file /home/ec2-user/ads/aws-discovery-agent.rpm ~中略~ ************************************************** FINISH PHASE ************************************************** Notice: By installing the Amazon Discovery Agent, you agree that your use is subject to the terms of your existing AWS Customer Agreement or other agreement with Amazon Web Services, Inc. or its affiliates governing your use of AWS services. You may not install and use the Amazon Discovery Agent unless you have an account in good standing with AWS. * * * Current running agent reports version as: 2.0.1618.0 This install script was created to install agent version: 2.0.1618.0 In most cases, these version numbers should be the same. [ec2-user@bastin ads]$ [ec2-user@bastin ads]$ echo $? 0 [ec2-user@bastin ads]$ エージェントの起動確認 [ec2-user@bastin ads]$ sudo systemctl status aws-discovery-daemon.service ● aws-discovery-daemon.service - AWS Discovery Agent: Collects system configuration and usage statistics for AWS Discovery. Loaded: loaded (/usr/lib/systemd/system/aws-discovery-daemon.service; enabled; vendor preset: disabled) Active: active (running) since Fri 2020-10-02 21:23:42 JST; 59s ago Main PID: 11023 (aws-discoveryd) CGroup: /system.slice/aws-discovery-daemon.service └─11023 /opt/aws/discovery/aws-discoveryd nodaemon Oct 02 21:23:43 bastin aws-discoveryd[11023]: values Oct 02 21:23:43 bastin aws-discoveryd[11023]: (?, ?, ?, ?, ?, ?, ?) Oct 02 21:23:43 bastin aws-discoveryd[11023]: [2020-10-02 21:23:43.355855] [0xf7d19700] [debug] Executing SQL REPLACE INTO commit_points (id, high_seq_num, end_time, end_utc_offset ) VALUES ('LastCommit', 1, 1601641423355, 540 ) Oct 02 21:23:43 bastin aws-discoveryd[11023]: [2020-10-02 21:23:43.355915] [0xf7d19700] [debug] Executing SQL DELETE FROM last_known_states WHERE commit_point_id = 'LastCommit' Oct 02 21:23:43 bastin aws-discoveryd[11023]: [2020-10-02 21:23:43.355958] [0xf7d19700] [debug] Executing SQL INSERT INTO last_known_states (commit_point_id, type, state, event_seq_num, event_time, event_utc_offset ) VALUES ('LastCommit', 1, 0, 1, 1601641423355, 540 ) Oct 02 21:23:43 bastin aws-discoveryd[11023]: [2020-10-02 21:23:43.356013] [0xf7d19700] [debug] Executing SQL INSERT INTO last_known_states (commit_point_id, type, state, event_seq_num, event_time, event_utc_offset ) VALUES ('LastCommit', 3, 0, 1, 1601641423355, 540 ) Oct 02 21:23:43 bastin aws-discoveryd[11023]: [2020-10-02 21:23:43.356044] [0xf7d19700] [debug] Executing SQL INSERT INTO last_known_states (commit_point_id, type, state, event_seq_num, event_time, event_utc_offset ) VALUES ('LastCommit', 2, 0, 1, 1601641423355, 540 ) Oct 02 21:23:43 bastin aws-discoveryd[11023]: [2020-10-02 21:23:43.356070] [0xf7d19700] [debug] Executing SQL INSERT INTO last_known_states (commit_point_id, type, state, event_seq_num, event_time, event_utc_offset ) VALUES ('LastCommit', 5, 0, 1, 1601641423355, 540 ) Oct 02 21:23:43 bastin aws-discoveryd[11023]: [2020-10-02 21:23:43.356094] [0xf7d19700] [debug] Executing SQL INSERT INTO last_known_states (commit_point_id, type, state, event_seq_num, event_time, event_utc_offset ) VALUES ('LastCommit', 4, 0, 1, 1601641423355, 540 ) Oct 02 21:23:43 bastin aws-discoveryd[11023]: [2020-10-02 21:23:43.356116] [0xf7d19700] [debug] Executing SQL COMMIT TRANSACTION commit_states Hint: Some lines were ellipsized, use -l to show in full. [ec2-user@bastin ads]$ ログ・ファイルや設定ファイルの配置場所 ログ・ファイル /var/log/aws/discovery/ 設定ファイル /var/opt/aws/discovery/ Data Collector チェックを入れてデータ収集を開始する。 データ収集を開始する。ここでAmazon Athenaでデータ探索を有効にするとKinesis経由でS3にデータが保存される。 収集されるデータ サーバ基本情報 パフォーマンス情報 収集される情報は次の通り。 https://docs.aws.amazon.com/ja_jp/application-discovery/latest/userguide/agent-data-collected.html 検出エージェントで収集されるデータ 他の機能 EC2インスタンスの推奨事項も検出してくれる。 --- ### awsetsを使用してAWSリソース情報を出力する date: 2020-10-05 url: https://zatoima.github.io/aws-awssets-list-resources.html tags: AWS, EC2, awsets A utility for crawling an AWS account and exporting all its resources for further analysis.とあるようにAWSアカウントに紐づくAWSリソースをjson形式で出力してくれるツール。 GitHub - trek10inc/awsets: A utility for crawling an AWS account and exporting all its resources for further analysis. https://github.com/trek10inc/awsets 現時点の最新のバージョンである0.4.1のバージョンでざっくりやってみたのでメモ。既にAWS CLIを実行出来る環境の場合はサクッとインストール、実行することが出来る。 インストール cd /home/ec2-user mkdir awsets cd awsets wget https://github.com/trek10inc/awsets/releases/download/v0.4.1/awsets_0.4.1_linux_x86_64.tar.gz tar xvfz awsets_0.4.1_linux_x86_64.tar.gz export PATH=PATH=$PATH:/home/ec2-user/awsets/ 実行 awsets list --regions ap-northeast-1 -o ec2.json --include ec2 awsets list --regions ap-northeast-1 -o elasticsearch.json --include elasticsearch awsets list --regions ap-northeast-1 -o ecs.json --include ecs 他にも色々機能があるらしい。参考のリンク、公式githubを参照。 参考 AWSのリソース一覧を出力できるツール AWSets を試してみた - Qiita https://qiita.com/hayao_k/items/837e176e9d16101e09b1 --- ### ハードウェア専有インスタンス (Dedicated Instance) とAmazon EC2 Dedicated Hostの違い date: 2020-10-03 url: https://zatoima.github.io/aws-ec2-dedicated-instance-host.html tags: AWS, EC2, SAP勉強 いつもこの2つの機能差異を忘れてしまうのでメモ。 2011/3からあるハードウェア専有インスタンスで実施出来なかった多くのことが2015年11月くらいから使えるAmazon EC2 Dedicated Hostで出来るようになっている。Dedicated Hosts では、物理サーバーに配置されたインスタンスの状況に関する可視性と制御がユーザ側が実施でできるためオンプレミスのサーバー限定のソフトウェアライセンスを使用でき、コンプライアンスを遵守出来る。 https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/dedicated-hosts-overview.html#dedicated-hosts-dedicated-instances 項目 Dedicated Host ハードウェア専有インスタンス 請求 ホストごとの請求 インスタンスごとの請求 ソケット、コア、ホスト ID の可視性 ソケットと物理コアの数が見える 可視性なし ホストおよびインスタンスアフィニティ インスタンスを同じ物理サーバーに徐々にデプロイし続けることができる サポート外 ターゲットを絞ったインスタンスの配置 インスタンスを物理サーバーに配置する方法についての可視性と制御が高い サポート外 インスタンスの自動復旧 サポート対象。詳細については、「ホスト復旧」を参照してください。 サポート対象 自分のライセンス使用 (BYOL) サポート対象 サポート外 --- ### Python(pyautogui)とLINE Notifyを利用してWeb画面変化をキャッチしてLINE通知する date: 2020-10-01 url: https://zatoima.github.io/python-line-notify-web-screan.html tags: Python, LINE Notify 表題の通り、Web画面変化を定期的にチェックして期待する画面になった場合にLINE Notifyを利用してチェックする簡単なスクリプト。 LINE Notifyの設定自体は大変簡単です。 [超簡単]LINE notify を使ってみる - Qiita https://qiita.com/iitenkida7/items/576a8226ba6584864d95 当初はRequestsやSeleniumを使用を想定していましたが、アクセスしたいサイトに対してuser-agentを偽装してもaccess deniedでどうしようも無かったのでpyautoguiを利用して期待する画像がWeb画面に表示されたら通知が飛ぶようにしました。pyautoguiはUWSCよりも簡単…! こちらのスクリプト上、URLはダミーのものを入れております。 import webbrowser import datetime import pyautogui import time import sys import requests def main(): while True: time.sleep(300) check_web() if pos is not None: send_line_notify(sent_message) send_gazo() else: continue def send_line_notify(notification_message): line_notify_token = 'xxxxxxxxxxxxxxxxxxxxxxxxxx' line_notify_api = 'https://notify-api.line.me/api/notify' headers = {'Authorization': f'Bearer {line_notify_token}'} data = {'message': f'message: {notification_message}'} requests.post(line_notify_api, headers = headers, data = data) def send_gazo(): line_notify_token = 'xxxxxxxxxxxxxxxxxxxxxxxx' line_notify_api = 'https://notify-api.line.me/api/notify' headers = {'Authorization': f'Bearer {line_notify_token}'} message = 'Screanshot for python script!' payload = {"message" : message} files = {"imageFile":open('D:\\tool\\py\\screanshot.jpg','rb')} post = requests.post(line_notify_api ,headers = headers ,params=payload,files=files) def check_web(): #ブラウザでURLを開く webbrowser.open('https://www.google.com/') #完全に表示されるまで待機 time.sleep(20) #エラー画面が表示されていないか"pyautogui.locateOnScreen"で判定 pos_check pos_check=pyautogui.locateOnScreen('D:\\tool\\py\\access_denied.jpg', confidence=0.6) #print(pos_check) if pos_check is not None: print("エラーのためスリープ") #エラーのスクリーンショットを記録 pyautogui.screenshot('D:\\tool\\py\\error.jpg') time.sleep(3600) #confidenceを微調整 #表示された画面に画像がどこの座標にあるかチェックする pos=pyautogui.locateOnScreen('D:\\tool\\py\\google.jpg', confidence=0.6) #print(pos) #期待する画面が表示されている場合にLINEで飛ばすメッセージをセットする if pos is not None: global sent_message sent_message='LINE Notify Message xxxxxxxxxxxxxxxxxx' pyautogui.screenshot('D:\\tool\\py\\screanshot.jpg') else: print("該当無し") #sys.exit() if __name__ == "__main__": main() --- ### EC2のハイパースレッディングを無効化する方法 date: 2020-09-30 url: https://zatoima.github.io/aws-ec2-cpu-hyper-threading.html tags: AWS, EC2 lscpuで確認した場合にハイパースレッディングが有効な場合は、Thread(s) per coreが2となる。 [ec2-user@ip-10-0-1-47 ~]$ lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 2 On-line CPU(s) list: 0,1 Thread(s) per core: 2 Core(s) per socket: 1 Socket(s): 1 NUMA node(s): 1 Vendor ID: GenuineIntel CPU family: 6 Model: 85 Model name: Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz Stepping: 7 CPU MHz: 2499.998 BogoMIPS: 4999.99 Hypervisor vendor: KVM Virtualization type: full L1d cache: 32K L1i cache: 32K L2 cache: 1024K L3 cache: 36608K NUMA node0 CPU(s): 0,1 Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 ida arat pku ospke cpuinfoを確認するとこのような表示。 [ec2-user@ip-10-0-1-47 ~]$ cat /proc/cpuinfo | grep -e 'core id' -e processor processor : 0 core id : 0 processor : 1 core id : 0 ハイパースレッディングを無効化する方法1 下記コマンドを実行するこの環境の場合、cpu0とcpu1があって、CPU1の方を無力化する。この場合、ハイパースレッディングは無効化されるが、再起動した場合には元に戻ってしまう。再起動時に同じコマンドを叩くということも選択肢となるが、スクリプトを作るなど多少の面倒くささが残る。 sudo su - echo 0 > /sys/devices/system/cpu/cpu1/online ハイパースレッディングを無効化する方法2 CPU オプションの最適化 - Amazon Elastic Compute Cloud https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/instance-optimize-cpu.html#instance-cpu-options-rules 上記マニュアルにある通り、インスタンスの作成時にのみCPUオプションを選択出来るようになっている。この機能を使用可能なインスタンスタイプの場合は、インスタンス作成時にこんな選択画面が表示される。 ここのコアごとのスレッドを1にすることでハイパースレッディングを無効化することも出来る。AWS CLIで指定することも可能で、その場合は次の通り--cpu-optionsを指定する。 aws ec2 run-instances --image-id ami-xxxxxxxx --instance-type m5.large --cpu-options "CoreCount=1,ThreadsPerCore=1" --key-name keypair 起動後に設定を確認する。 [ec2-user@bastin ~]$ aws ec2 describe-instances --instance-ids i-01842d7da54e0c630 --query "Reservations[].Instances[].CpuOptions" [ { "CoreCount": 1, "ThreadsPerCore": 1 } ] lscpuコマンドを叩いた場合にも、ハイパースレッディングが無効化されていることを確認出来る。 [root@ip-10-0-1-47 ~]# lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 2 On-line CPU(s) list: 0 Off-line CPU(s) list: 1 Thread(s) per core: 1 Core(s) per socket: 1 Socket(s): 1 NUMA node(s): 1 Vendor ID: GenuineIntel CPU family: 6 Model: 85 Model name: Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz Stepping: 7 CPU MHz: 2499.998 BogoMIPS: 4999.99 Hypervisor vendor: KVM Virtualization type: full L1d cache: 32K L1i cache: 32K L2 cache: 1024K L3 cache: 36608K NUMA node0 CPU(s): 0 Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 ida arat pku ospke その他 Amazon EC2 インスタンスタイプ https://aws.amazon.com/jp/ec2/instance-types/ M6g インスタンス、A1 インスタンス、T2 インスタンス、m3.medium を除き、各 vCPU はインテル Xeon コアまたは AMD EPYC コア上のスレッドです。 上記の通り、いくつかのインスタンスは最初からハイパースレッディングは無効となっている。ハイパースレッディングという用語はIntel用語なので、AMDには適用されないため、スレッドという言い方をしていると推測。 --- ### AWSのドキュメントの更新履歴をgithubで確認してRSSフィードを取得 date: 2020-09-04 url: https://zatoima.github.io/aws-docs-guthub-commit-log.html tags: AWS, Aurora 今更ながらAWSのドキュメントがgithubから確認出来ることを知った。2018年にオープンソースになった模様。 AWS ドキュメントがオープンソースになり、GitHub でご利用可能に | Amazon Web Services ブログ https://aws.amazon.com/jp/blogs/news/aws-documentation-is-now-open-source-and-on-github/ 下記のURLからユーザガイドや開発者ガイドのリポジトリにアクセスすることが出来る。 https://github.com/awsdocs 例えばAuroraのユーザガイドのリポジトリはこちら。 https://github.com/awsdocs/amazon-aurora-user-guide githubなのでcommitのログも確認出来るし、具体的にどこの部分が変わったか、というのも見ることが出来る。 https://github.com/awsdocs/amazon-aurora-user-guide/commit/f83c1cce2f8fa9bbb7bc4c72ac2233c381f9bd84 GitHubは色々なatomフィードを出力出来るのでRSSに登録しといて、更新があれば確認してみる、というような使い方も出来る。例えば、Auroraのユーザガイドのcommitログのフィードは下記となる。リポジトリ名をそれぞれのものに変えることで気にあるリポジトリの更新を受け取ることが出来るのでこういう使い方も。 https://github.com/awsdocs/amazon-aurora-user-guide/commits/master.atom 私はFeedlyを使っているが、こんな感じに通知が飛んでくる。 --- ### ALB(Application Load Balancer)のログをAthenaで分析 date: 2020-09-02 url: https://zatoima.github.io/aws-athena-alb-log-analitics.html tags: AWS, ALB, Athena ELBのログの有効化 属性の「属性の編集」からアクセスログを有効化。しばらく放置するとS3の指定したバケットにELBにログが蓄積されていく。 Athena Athenaでデータベース作成 create database alb_db Athenaでテーブル作成 LOCATIONに指定するパスはELBアクセスログの設定した時に指定したBucketとpathとなる。このテーブル作成後は、Athenaを使用してSQLベースでクエリを発行することが出来る。 CREATE EXTERNAL TABLE IF NOT EXISTS alb_logs ( type string, time string, elb string, client_ip string, client_port int, target_ip string, target_port int, request_processing_time double, target_processing_time double, response_processing_time double, elb_status_code string, target_status_code string, received_bytes bigint, sent_bytes bigint, request_verb string, request_url string, request_proto string, user_agent string, ssl_cipher string, ssl_protocol string, target_group_arn string, trace_id string, domain_name string, chosen_cert_arn string, matched_rule_priority string, request_creation_time string, actions_executed string, redirect_url string, lambda_error_reason string, target_port_list string, target_status_code_list string, new_field string ) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe' WITH SERDEPROPERTIES ( 'serialization.format' = '1', 'input.regex' = '([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*):([0-9]*) ([^ ]*)[:-]([0-9]*) ([-.0-9]*) ([-.0-9]*) ([-.0-9]*) (|[-0-9]*) (-|[-0-9]*) ([-0-9]*) ([-0-9]*) \"([^ ]*) ([^ ]*) (- |[^ ]*)\" \"([^\"]*)\" ([A-Z0-9-]+) ([A-Za-z0-9.-]*) ([^ ]*) \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" ([-.0-9]*) ([^ ]*) \"([^\"]*)\" \"([^\"]*)\" \"([^ ]*)\" \"([^\s]+)\" \"([^\s]+)\"(.*)') LOCATION 's3://<Bucket name>/AWSLogs/<Account ID>/elasticloadbalancing/ap-northeast-1/'; このテーブル作成後は、Athenaを使用してSQLベースでクエリを発行することが出来る。作成後のテーブル↓ 各列の説明は下記を参照。 https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-access-logs.html Field 説明: type リクエストまたは接続のタイプ。有効な値は次のとおりです (その他の値は無視してください)。http — HTTPhttps — HTTP over SSL/TLSh2 — HTTP/2 over SSL/TLSws — WebSocketswss — WebSockets over SSL/TLS time ロードバランサーがクライアントに対してレスポンスを生成した時刻 (ISO 8601 形式)。WebSocket の場合、これは接続を閉じる時間です。 elb ロードバランサーのリソース ID。アクセスログエントリを解析する場合、リソース ID にはスラッシュ (/) を含めることができます。 client:port リクエストを送信したクライアントの IP アドレスとポート。 target:port このリクエストを処理したターゲットの IP アドレスとポート。クライアントがリクエスト全体を送信しなかった場合、ロードバランサーはターゲットにリクエストをディスパッチできず、この値が - に設定されます。ターゲットが Lambda 関数の場合、この値は - に設定されます。リクエストが AWS WAF によってブロックされた場合、この値は - に設定され、elb_status_code の値は 403 に設定されます。 request_processing_time ロードバランサーがリクエストを受け取った時点からターゲットに送信するまでの合計経過時間 (ミリ秒精度の秒単位)。ロードバランサーがリクエストをターゲットにディスパッチできない場合、この値は -1 に設定されます。この状況が発生するのは、ターゲットがアイドルタイムアウト前に接続を閉じた場合か、クライアントが誤った形式のリクエストを送信した場合です。登録済みターゲットからアイドルタイムアウトまで応答がない場合にも、この値は -1 に設定される場合があります。 target_processing_time ロードバランサーがターゲットにリクエストを送信した時点から、そのターゲットが応答ヘッダーの送信を開始した時点までの合計経過時間 (ミリ秒精度の秒単位)。ロードバランサーがリクエストをターゲットにディスパッチできない場合、この値は -1 に設定されます。この状況が発生するのは、ターゲットがアイドルタイムアウト前に接続を閉じた場合か、クライアントが誤った形式のリクエストを送信した場合です。登録済みターゲットからアイドルタイムアウトまで応答がない場合にも、この値は -1 に設定される場合があります。 response_processing_time ロードバランサーがターゲットから応答ヘッダーを受け取った時点から、クライアントへの応答の送信を開始した時点までの合計経過時間 (ミリ秒精度の秒単位)。これには、ロードバランサーでの待機時間と、ロードバランサーからクライアントへの接続の取得時間の両方が含まれます。ロードバランサーがリクエストをターゲットに送信できない場合、この値は -1 に設定されます。この状況が発生するのは、ターゲットがアイドルタイムアウト前に接続を閉じた場合か、クライアントが誤った形式のリクエストを送信した場合です。 elb_status_code ロードバランサーからの応答のステータスコード。 target_status_code ターゲットから応答のステータスコード。この値は、ターゲットへの接続が確立され、ターゲットが応答を送信した場合のみ記録されます。それ以外の場合は、- に設定されます。 received_bytes クライアント (リクエスタ) から受け取ったリクエストのサイズ (バイト単位)。HTTP リクエストの場合、これにはヘッダーが含まれます。WebSocket の場合、これは接続でクライアントから受信した合計バイト数です。 sent_bytes クライアント (リクエスタ) に返される応答のサイズ(バイト単位)。HTTP リクエストの場合、これにはヘッダーが含まれます。WebSocket の場合、これは接続でクライアントに送信した合計バイト数です。 “request” クライアントからのリクエスト行。二重引用符で囲まれ、次の形式でログされます。HTTP メソッド + プロトコル://host:port/uri + HTTP バージョン。ロードバランサーは、リクエスト URI を記録するときに、クライアントから送信された URL をそのまま保持します。アクセスログファイルのコンテンツタイプは設定されません。このフィールドを処理するときは、クライアントが URL を送信した方法を考慮してください。 “user_agent” リクエスト元のクライアントを特定する User-Agent 文字列 (二重引用符で囲まれます)。この文字列は、1 つ以上の製品 ID (製品[/バージョン]) から構成されます。文字列が 8 KB より長い場合は切り捨てられます。 ssl_cipher [HTTPS リスナー] SSL 暗号。リスナーが HTTPS リスナーではない場合、この値は - に設定されます。 ssl_protocol [HTTPS リスナー] SSL プロトコル。リスナーが HTTPS リスナーではない場合、この値は - に設定されます。 target_group_arn ターゲットグループの Amazon リソースネーム (ARN)。 “trace_id” X-Amzn-Trace-Id ヘッダーのコンテンツ (二重引用符で囲まれます)。 <domain_name> [HTTPS リスナー] TLS ハンドシェイク中にクライアントから提供される SNI ドメイン (二重引用符で囲まれます)。クライアントが SNI をサポートしない場合、あるいはドメインが証明書と一致せず、デフォルトの証明書がクライアントに提示された場合、この値は - となります。 chosen_cert_arn [HTTPS リスナー] クライアントに提示される証明書の ARN (二重引用符で囲まれます)。セッションが再利用される場合、この値は session-reused に設定されます。リスナーが HTTPS リスナーではない場合、この値は - に設定されます。 matched_rule_priority リクエストに一致したルールの優先度の値。ルールが一致した場合、この値は 1~50,000 になります。一致するルールがなく、デフォルトのアクションが実行された場合、この値は 0 に設定されます。ルールの評価中にエラーが発生した場合は、-1 に設定されます。その他のエラーの場合は、- に設定されます。 request_creation_time ロードバランサーがクライアントからリクエストを受け取った時刻 (ISO 8601 形式)。 “actions_executed” リクエストの処理時に実行されるアクション (二重引用符で囲まれます)。この値は、「Actions taken」で説明されている値を含めることができるカンマ区切りリストです。形式が正しくないリクエストなどでアクションが実行されない場合、この値は - に設定されます。 “redirect_url” HTTP レスポンスのロケーションヘッダーのリダイレクトターゲットの URL (二重引用文字で囲む)。リダイレクトアクションが実行されなかった場合、この値は - に設定されます。 “error_reason” エラー理由コード (二重引用符で囲まれます)。リクエストが失敗した場合、これは「Error reason codes」で説明されているいずれかのエラーコードになります。実行されたアクションが認証アクションを含まない、またはターゲットが Lambda 関数ではない場合、この値は - に設定されます。 “target:port_list” このリクエストを処理したターゲットの IP アドレスとポートのスペース区切りのリスト (二重引用符で囲まれます)。現在、このリストには 1 つの項目を含めることができ、target:port フィールドと一致します。クライアントがリクエスト全体を送信しなかった場合、ロードバランサーはターゲットにリクエストをディスパッチできず、この値が - に設定されます。ターゲットが Lambda 関数の場合、この値は - に設定されます。リクエストが AWS WAF によってブロックされた場合、この値は - に設定され、elb_status_code の値は 403 に設定されます。 “target_status_code_list” ターゲットの応答からのステータスコードのスペース区切りのリスト (二重引用符で囲まれます)。現在、このリストには 1 つの項目を含めることができ、target_status_code フィールドと一致します。この値は、ターゲットへの接続が確立され、ターゲットが応答を送信した場合のみ記録されます。それ以外の場合は、- に設定されます。 クエリサンプル例はこちら。外向けに公開しているELBの場合、怪しげのアタックがたくさん来ていることがわかると思います。 最初の 100 個のアクセスログエントリを新しい順に表示 SELECT * FROM alb_logs ORDER by time ASC LIMIT 100; ALB にアクセスしたすべてのクライアント IP アドレスと、それらが ALB にアクセスした回数を一覧表示 SELECT distinct client_ip, count() as count from alb_logs GROUP by client_ip ORDER by count() DESC; リクエスト/レスポンスのペアで ALB を通過しているデータの平均量 (キロバイト) を一覧表示 SELECT (avg(sent_bytes)/1000.0 + avg(received_bytes)/1000.0) as prewarm_kilobytes from alb_logs; 指定された URL を訪問した回数をクライアント別、降順に一覧表示 SELECT client_ip, elb, request_url, count(*) as count from alb_logs GROUP by client_ip, elb, request_url ORDER by count DESC; Firefox ユーザーが最も頻繁にアクセスした上位 10 個の URL を一覧表示 SELECT request_url, user_agent, count(*) as count FROM alb_logs WHERE user_agent LIKE '%Firefox%' GROUP by request_url, user_agent ORDER by count(*) DESC LIMIT 10; ALB へのリクエストで送信したデータ量 (メガバイト) で、クライアント別、降順で一覧表示 SELECT client_ip, sum(received_bytes/1000000.0) as client_datareceived_megabytes FROM alb_logs GROUP by client_ip ORDER by client_datareceived_megabytes DESC; 参考 Athena を使用してロードバランサーのアクセスログを分析する https://aws.amazon.com/jp/premiumsupport/knowledge-center/athena-analyze-access-logs/ --- ### ユーザデータを使用してEC2作成時にApacheを自動インストール date: 2020-08-31 url: https://zatoima.github.io/aws-ec2-userdata-apache-install.html tags: AWS, EC2 ユーザデータとは? Linuxインスタンスの初期起動時に実行するコマンドを指す。デフォルトでは初期起動時のみですが、再起動時に毎回実行するということも出来る模様。 https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/user-data.html Amazon EC2 でインスタンスを起動するとき、起動後にそのインスタンスにユーザーデータを渡し、一般的な自動設定タスクを実行したり、スクリプトを実行したりできます。2 つのタイプのユーザーデータを Amazon EC2 に渡すことができます。 ユーザデータの設定方法 ステップ 3: インスタンスの詳細の設定 の 高度な詳細欄にユーザデータを指定する欄があります。 ユーザデータには下記を指定。yum update、Apacheのインストールから権限変更などを実施。 #!/bin/bash yum update -y amazon-linux-extras install -y lamp-mariadb10.2-php7.2 php7.2 yum install -y httpd mariadb-server systemctl start httpd systemctl enable httpd usermod -a -G apache ec2-user chown -R ec2-user:apache /var/www chmod 2775 /var/www find /var/www -type d -exec chmod 2775 {} \; find /var/www -type f -exec chmod 0664 {} \; echo `hostname` > /var/www/html/index.html 後はこの状態で他のEC2作成と同じように進めることでインスタンス作成時にApacheインストールまで実施される。セキュリティグループなどの設定は割愛します。 --- ### RDS Proxyを使用してAurora PostgreSQLのフェイルオーバーを実行する date: 2020-08-29 url: https://zatoima.github.io/aws-postgresql-rdsproxy-failover.html tags: AWS, Aurora, PostgreSQL RDS Proxyを触って見つつ、フェイルオーバーがどのくらいで完了するのか、動きを含めて確認してみたいという目的。 従来のクラスタエンドポイントの場合は、DNSを利用してWriter と Readerの切替を実装しているが、RDS Proxyの場合は、アプリケーションとRDS Proxyの接続は維持したままで、DB側のフェイルオーバーを検出してシームレスに接続する。アプリケーションから再接続やDNSのTTLの考慮が不要になる。トランザクション中やクエリ処理中の接続は再接続が必要。 Amazon RDS Proxy のご紹介 https://pages.awscloud.com/rs/112-TZM-766/images/EV_amazon-rds-aws-lambda-update_Jul28-2020_RDS_Proxy.pdf というわけでクラスタエンドポイントを使用するパターンとRDS Proxyを使用するパターンでフェイルオーバーや実施してみる。 パターン1:クラスタエンドポイントで実施パターン 適当に下記スクリプトを実行してタイムスタンプをテーブルに記録してスクリプト実行中に手動フェイルオーバーを実行する。 テストスクリプト 1秒ごとにINSERTを実施 #! /bin/bash while true do #truncate table record; #create table record(id serial,create_at timestamp); DATETIME=$(date -u "+%Y-%m-%d %T.%N") echo $DATETIME psql -q -h a-pgsql.cluster-xxxxx.ap-northeast-1.rds.amazonaws.com -d postgres -U postgres -c "insert into record(create_at) VALUES (current_timestamp)" & sleep 1 done フェイルオーバー自体に掛かった時間 約30秒弱でフェイルオーバー自体は完了 時間 システムノート August 29th 2020, 11:44:48 am UTC Completed failover to DB instance: a-pgsql-instance-1-ap-northeast-1a August 29th 2020, 11:44:23 am UTC Started cross AZ failover to DB instance: a-pgsql-instance-1-ap-northeast-1a bashの実行ログ フェイルオーバーの開始から完了までデータベースが使えなくなるというわけではなく、11:44:29から11:44:40 の約11秒間でフェイルオーバーに伴いエラーが出ている 2020-08-29 11:44:27.964959626 2020-08-29 11:44:28.966971425 2020-08-29 11:44:29.968957489 WARNING: terminating connection because of crash of another server process DETAIL: The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory. HINT: In a moment you should be able to reconnect to the database and repeat your command. psql: SSL SYSCALL error: EOF detected SSL SYSCALL error: EOF detected connection to server was lost 2020-08-29 11:44:30.971007776 psql: could not connect to server: Connection refused Is the server running on host "a-pgsql.cluster-xxxxxx.ap-northeast-1.rds.amazonaws.com" (10.0.3.43) and accepting TCP/IP connections on port 5432? 2020-08-29 11:44:31.972952018 2020-08-29 11:44:32.974997039 2020-08-29 11:44:33.977032145 psql: FATAL: the database system is starting up FATAL: the database system is starting up psql: FATAL: the database system is starting up FATAL: the database system is starting up psql: FATAL: the database system is starting up FATAL: the database system is starting up 2020-08-29 11:44:34.979111133 ERROR: cannot execute INSERT in a read-only transaction 2020-08-29 11:44:35.981149831 ERROR: cannot execute INSERT in a read-only transaction 2020-08-29 11:44:36.983173817 ERROR: cannot execute INSERT in a read-only transaction 2020-08-29 11:44:37.985163358 ERROR: cannot execute INSERT in a read-only transaction 2020-08-29 11:44:38.987178155 ERROR: cannot execute INSERT in a read-only transaction 2020-08-29 11:44:39.989168920 2020-08-29 11:44:40.991212531 2020-08-29 11:44:41.993185159 2020-08-29 11:44:42.995173285 2020-08-29 11:44:43.997177503 2020-08-29 11:44:44.999206797 2020-08-29 11:44:46.001261962 2020-08-29 11:44:47.003287661 2020-08-29 11:44:48.005291195 データベース側に記録された時間 bashで接続エラーがあった11:44:29から11:44:40 あたりのINSERT分が抜けている。十分短いが、、、 | 1065 | 2020-08-29 11:44:19.974279 | | 1066 | 2020-08-29 11:44:20.976299 | | 1067 | 2020-08-29 11:44:21.984021 | | 1068 | 2020-08-29 11:44:22.981434 | | 1069 | 2020-08-29 11:44:23.982408 | | 1070 | 2020-08-29 11:44:24.984163 | | 1071 | 2020-08-29 11:44:25.986223 | | 1072 | 2020-08-29 11:44:26.991738 | | 1073 | 2020-08-29 11:44:28.024189 | | 1090 | 2020-08-29 11:44:40.040502 | | 1091 | 2020-08-29 11:44:41.006773 | | 1092 | 2020-08-29 11:44:42.012005 | | 1093 | 2020-08-29 11:44:43.010699 | | 1094 | 2020-08-29 11:44:44.014737 | | 1095 | 2020-08-29 11:44:45.089499 | | 1096 | 2020-08-29 11:44:46.020322 | | 1097 | 2020-08-29 11:44:47.01858 | | 1098 | 2020-08-29 11:44:48.024825 | | 1099 | 2020-08-29 11:44:49.028113 | | 1100 | 2020-08-29 11:44:50.026786 | パターン2:RDS Proxyで実施パターン パターン1と同じ手順でスクリプトを実行してフェイルオーバーに掛かる時間やDBへの接続状況などを見てみる。RDS Proxyのエンドポイントを接続先に指定。 スクリプト #! /bin/bash while true do #truncate table record; #create table record(id serial,create_at timestamp); DATETIME=$(date -u "+%Y-%m-%d %T.%N") echo $DATETIME psql -q -h proxy-aurora.proxy-xxxxx.ap-northeast-1.rds.amazonaws.com -d postgres -U postgres -c "insert into record(create_at) VALUES (current_timestamp)" & sleep 0.5 done フェイルオーバー自体に掛かった時間 約36秒でフェイルオーバーは完了 時間 システムノート August 29th 2020, 12:05:03 pm UTC Completed failover to DB instance: a-pgsql-instance-1 August 29th 2020, 12:04:39 pm UTC Started cross AZ failover to DB instance: a-pgsql-instance-1 bashの実行ログ フェイルオーバーに伴い12:04:48あたりでエラーが出ているが、クラスタエンドポイントを使用したパターン①の検証と異なりエラー自体の傾向が異なる 2020-08-29 12:04:30.095671574 2020-08-29 12:04:31.097629856 2020-08-29 12:04:32.099684736 2020-08-29 12:04:33.101745645 2020-08-29 12:04:34.103755036 2020-08-29 12:04:35.105731120 2020-08-29 12:04:36.107736230 2020-08-29 12:04:37.109709993 2020-08-29 12:04:38.111698832 2020-08-29 12:04:39.113675005 2020-08-29 12:04:40.115698907 2020-08-29 12:04:41.117673464 2020-08-29 12:04:42.119682149 2020-08-29 12:04:43.121650566 2020-08-29 12:04:44.123618407 2020-08-29 12:04:45.125820156 2020-08-29 12:04:46.127808056 2020-08-29 12:04:47.129771043 2020-08-29 12:04:48.131772090 WARNING: terminating connection because of crash of another server process DETAIL: The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory. HINT: In a moment you should be able to reconnect to the database and repeat your command. SSL connection has been closed unexpectedly connection to server was lost WARNING: terminating connection because of crash of another server process DETAIL: The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory. HINT: In a moment you should be able to reconnect to the database and repeat your command. SSL connection has been closed unexpectedly connection to server was lost 2020-08-29 12:04:49.133763120 2020-08-29 12:04:50.135776827 2020-08-29 12:04:51.137775212 2020-08-29 12:04:52.139811209 2020-08-29 12:04:53.141852628 2020-08-29 12:04:54.143861363 2020-08-29 12:04:55.145887875 2020-08-29 12:04:56.147877446 2020-08-29 12:04:57.149851817 2020-08-29 12:04:58.151858291 2020-08-29 12:04:59.153685252 2020-08-29 12:05:00.155651975 2020-08-29 12:05:01.157824634 2020-08-29 12:05:02.159847039 2020-08-29 12:05:03.161849475 2020-08-29 12:05:04.163848675 2020-08-29 12:05:05.165860863 2020-08-29 12:05:06.167913253 2020-08-29 12:05:07.169922306 2020-08-29 12:05:08.171957895 2020-08-29 12:05:09.173986169 2020-08-29 12:05:10.175984477 2020-08-29 12:05:11.177993763 2020-08-29 12:05:12.180028575 2020-08-29 12:05:13.182031977 2020-08-29 12:05:14.184081473 データベース側に記録された時間 12:04:46から12:04:53の間で更新が止まっていますが、約7秒で切り替わったことが分かる | 1170 | 2020-08-29 12:04:39.156067 | | 1171 | 2020-08-29 12:04:40.240195 | | 1172 | 2020-08-29 12:04:41.161005 | | 1173 | 2020-08-29 12:04:42.189308 | | 1174 | 2020-08-29 12:04:43.318342 | | 1175 | 2020-08-29 12:04:44.227378 | | 1176 | 2020-08-29 12:04:45.167466 | | 1177 | 2020-08-29 12:04:46.247739 | | 1189 | 2020-08-29 12:04:53.329366 | | 1190 | 2020-08-29 12:04:53.339468 | | 1191 | 2020-08-29 12:04:53.353239 | | 1192 | 2020-08-29 12:04:53.380346 | | 1193 | 2020-08-29 12:04:53.391141 | | 1194 | 2020-08-29 12:04:54.204525 | | 1195 | 2020-08-29 12:04:55.284926 | | 1196 | 2020-08-29 12:04:56.199496 | | 1197 | 2020-08-29 12:04:57.222213 | | 1198 | 2020-08-29 12:04:58.297598 | | 1199 | 2020-08-29 12:04:59.192773 | | 1200 | 2020-08-29 12:05:00.26938 | | 1201 | 2020-08-29 12:05:01.217964 | | 1202 | 2020-08-29 12:05:02.418454 | | 1203 | 2020-08-29 12:05:03.212937 | | 1204 | 2020-08-29 12:05:04.231207 | | 1205 | 2020-08-29 12:05:05.202887 | | 1206 | 2020-08-29 12:05:06.243436 | | 1207 | 2020-08-29 12:05:07.221574 | | 1208 | 2020-08-29 12:05:08.230837 | | 1209 | 2020-08-29 12:05:09.218686 | | 1210 | 2020-08-29 12:05:10.228458 | | 1211 | 2020-08-29 12:05:11.28525 | 何回か同じような検証を行った場合も RDS Proxy に掛かる時間は短かった。次はRDS Proxy を使用してLamdbaのコネクションプール的な使い方について整理したい。 参考資料 Amazon RDS Proxy を使用したアプリケーションの可用性の向上 | Amazon Web Services ブログ https://aws.amazon.com/jp/blogs/news/improving-application-availability-with-amazon-rds-proxy/ RDS Proxyを使うとDB接続処理は早くなるのか? | Developers.IO https://dev.classmethod.jp/articles/rds-proxy-connect-benchmark/ --- ### Amazon Elasicsearch Serviceの検索結果をCSV形式で出力 date: 2020-08-13 url: https://zatoima.github.io/aws-elasticsearch-csv-output.html tags: AWS, Elasicsearch 事前準備 jqコマンドとcsvkitに含まれるJSON形式の出力をCSVにするコマンドであるin2csvが必要となので事前にインストールする。Python環境も必要。 sudo yum -y install jq pip install csvkit CSV形式でElasicsearchの結果を取得 curl https://vpc-xxxxxxx-xxxxxx.ap-northeast-1.es.amazonaws.com/xxxxxxx/_search?pretty | jq [.hits.hits[]._source] | in2csv -f json --- ### ora2pgとSCTの変換結果の差異 date: 2020-07-30 url: https://zatoima.github.io/aws-sct-ora2pg-conversion-compare.html tags: AWS, SCT, Oracle, PostgreSQL, DB Migration 興味本位でOracleからPostgreSQLへスキーマ移行する場合によく使用されるora2pgとSCT(AWS Schema Conversion Tool )の変換結果を比較してみた。ora2pg、SCT共にデフォルト設定で実施してwinmergeで比較してみた。左側がSCT、右側がora2pgとなる。予想以上に結果が異なって驚いた。 ソースとなるOracle側に作ったテーブルはこちら。 CREATE文 CREATE TABLE "DATATYPES"( "BFILE" BFILE, "BINARY_FLOAT" BINARY_FLOAT, "BINARY_DOUBLE" BINARY_DOUBLE, "BLOB" BLOB, "CHAR" CHAR(10 BYTE), "CHARACTER" CHAR(10 BYTE), "CLOB" CLOB, "NCLOB" NCLOB, "DATE" DATE, "DECIMAL" NUMBER(3,2), "DEC" NUMBER(3,2), "DOUBLE_PRECISION" FLOAT(126), "FLOAT" FLOAT(3), "INTEGER" NUMBER(*,0), "INT" NUMBER(*,0), "INTERVAL_YEAR" INTERVAL YEAR(4) TO MONTH, "INTERVAL_DAY" INTERVAL DAY(4) TO SECOND(4), "LONG" LONG, "NCHAR" NCHAR(10), "NCHAR_VARYING" NVARCHAR2(10), "NUMBER" NUMBER(9,9), "NUMBER1" NUMBER(9,0), "NUMBER(*)" NUMBER, "NUMERIC" NUMBER(9,9), "NVARCHAR2" NVARCHAR2(10), "RAW" RAW(10), "REAL" FLOAT(63), "ROW_ID" ROWID, "SMALLINT" NUMBER(*,0), "TIMESTAMP" TIMESTAMP(5), "TIMESTAMP WITH TIME ZONE" TIMESTAMP(5) WITH TIME ZONE, "UROWID" UROWID(10), "VARCHAR" VARCHAR2(10 BYTE), "VARCHAR2" VARCHAR2(10 BYTE), "XMLTYPE" "PUBLIC"."XMLTYPE" ); テーブル定義 SQL> desc DATATYPES; Name Null? Type ----------------------------------------- -------- ---------------------------- BFILE BINARY FILE LOB BINARY_FLOAT BINARY_FLOAT BINARY_DOUBLE BINARY_DOUBLE BLOB BLOB CHAR CHAR(10) CHARACTER CHAR(10) CLOB CLOB NCLOB NCLOB DATE DATE DECIMAL NUMBER(3,2) DEC NUMBER(3,2) DOUBLE_PRECISION FLOAT(126) FLOAT FLOAT(3) INTEGER NUMBER(38) INT NUMBER(38) INTERVAL_YEAR INTERVAL YEAR(4) TO MONTH INTERVAL_DAY INTERVAL DAY(4) TO SECOND(4) LONG LONG NCHAR NCHAR(10) NCHAR_VARYING NVARCHAR2(10) NUMBER NUMBER(9,9) NUMBER1 NUMBER(9) NUMBER(* ) NUMBER NUMERIC NUMBER(9,9) NVARCHAR2 NVARCHAR2(10) RAW RAW(10) REAL FLOAT(63) ROW_ID ROWID SMALLINT NUMBER(38) TIMESTAMP TIMESTAMP(5) TIMESTAMP WITH TIME ZONE TIMESTAMP(5) WITH TIME ZONE UROWID ROWID VARCHAR VARCHAR2(10) VARCHAR2 VARCHAR2(10) XMLTYPE PUBLIC.XMLTYPE STORAGE BINARY 変換結果 表形式で記載。右側のora2pgとSCT側がPostgreSQL結果で\dで定義を出力した結果となる。 No. Oracle (※descの結果) SCT (\d メタコマンド結果) ora2pg (\d メタコマンド結果) 1 BINARY FILE LOB character varying(255) bytea 2 BINARY_FLOAT real double precision 3 BINARY_DOUBLE double precision double precision 4 BLOB bytea bytea 5 CHAR(10) character(10) character(10) 6 CHAR(10) character(10) character(10) 7 CLOB text text 8 NCLOB text text 9 DATE timestamp(0) without time zone timestamp without time zone 10 NUMBER(3,2) numeric(3,2) real 11 NUMBER(3,2) numeric(3,2) real 12 FLOAT(126) double precision double precision 13 FLOAT(3) double precision double precision 14 NUMBER(38) numeric(38,0) numeric(38,0) 15 NUMBER(38) numeric(38,0) numeric(38,0) 16 INTERVAL YEAR(4) TO MONTH interval year to month interval year to month 17 INTERVAL DAY(4) TO SECOND(4) interval day to second(4) interval day to second(4) 18 LONG text text 19 NCHAR(10) character(10) character(10) 20 NVARCHAR2(10) character varying(10) character varying(10) 21 NUMBER(9,9) numeric(9,9) double precision 22 NUMBER(9) numeric(9,0) integer 23 NUMBER double precision bigint 24 NUMBER(9,9) numeric(9,9) double precision 25 NVARCHAR2(10) character varying(10) character varying(10) 26 RAW(10) bytea bytea 27 FLOAT(63) double precision double precision 28 ROWID character(255) oid 29 NUMBER(38) numeric(38,0) numeric(38,0) 30 TIMESTAMP(5) timestamp(5) without time zone timestamp without time zone 31 TIMESTAMP(5) WITH TIME ZONE timestamp(5) with time zone timestamp with time zone 32 ROWID character varying oid 33 VARCHAR2(10) character varying(10) character varying(10) 34 VARCHAR2(10) character varying(10) character varying(10) 35 PUBLIC.XMLTYPE STORAGE BINARY xml xml --- ### SPARQLクエリ集メモ date: 2020-07-27 url: https://zatoima.github.io/sparql-query-note.html tags: SPARQL, Neptune, DBpedia 初見のSPARQLエンドポイントに向けて実行するSPARQLクエリをメモ。DBPediaのSPARQLエンドポイントでお試しください。 http://ja.dbpedia.org/sparql エンドポイントにどんなトリプルがあるのか SELECT * WHERE { ?s ?p ?o . } LIMIT 100 OFFSET 0 エンドポイントのトリプル数 SELECT (COUNT(*) AS ?count) WHERE { ?s ?p ?o . } 型の確認 SELECT DISTINCT ?type WHERE { ?s a ?type } どのようなプロパティがあるかを確認 SELECT DISTINCT ?p WHERE { ?s a <http://dbpedia.org/ontology/Anime> ; ?p ?o. } 名前付きグラフも合算してトリプル数を検索する SELECT (COUNT(*) AS ?count) WHERE { { ?s ?p ?o . } UNION { GRAPH ?g { ?s ?p ?o . } } } 名前付きグラフの一覧を取得する SELECT DISTINCT ?g WHERE { GRAPH ?g { ?s ?p ?o . } } 名前付きグラフ毎の件数を集計 SELECT ?g count(?g) WHERE {GRAPH ?g {?s ?p ?o}} GROUP BY ?g 名前付きグラフのデータを検索 SELECT * WHERE { GRAPH <あるグラフ> {?s ?p ?o }} プロパティの一覧を取得する SELECT DISTINCT ?p WHERE { ?s ?p ?o . } LIMIT 100 プロパティの一覧を使用頻度順に取得する SELECT ?p (COUNT(?p) AS ?count) WHERE { ?s ?p ?o . } GROUP BY ?p ORDER BY DESC(?count) LIMIT 100 主語あたりの平均プロパティ数 SELECT (AVG(?count) AS ?average) WHERE { SELECT ?s (COUNT(?p) as ?count) WHERE { ?s ?p ?o . } GROUP BY ?s } <検索データ>が含まれるデータを探したい(主語から探す) SELECT * { GRAPH ?g { ?s ?p ?o . FILTER( contains(str(?s),'<検索データ>') ) }} <検索データ>が含まれるデータを探したい(述語から探す) SELECT * { GRAPH ?g { ?s ?p ?o . FILTER( contains(str(?p),'<検索データ>') ) }} <検索データ>が含まれるデータを探したい(目的語から探す) SELECT * { GRAPH ?g { ?s ?p ?o . FILTER( contains(str(?o),'<検索データ>') ) }} グラフ完全一致でデータを探す SELECT * { GRAPH <グラフ> {?s ?p ?o}} 主語完全一致でデータを探す SELECT * { GRAPH ?g {<主語> ?p ?o}} 述語完全一致でデータを探す SELECT * { GRAPH ?g {?s <述語> ?o}} 目的語完全一致でデータを探す SELECT * { GRAPH ?g {?s ?p '目的語'}} 参考サイト: よく使うSPARQLサンプル集 - Qiita https://qiita.com/hodade/items/30158fba9e943132023f SPARQL入門 http://www.aise.ics.saitama-u.ac.jp/~gotoh/IntroSPARQL.html --- ### Amazon Elasticsearch Serviceでindex.max_result_windowの値を変更 date: 2020-07-25 url: https://zatoima.github.io/aws-elasticsearch-max_result_window_parameter.html tags: AWS, Elasticsearch Amazon Elasticsearch Service で index.max_result_window を変更する方法と確認する方法をメモ。変更に伴いクラスターのレイテンシーとメモリへの注意が必要。 Index modules | Elasticsearch Reference [7.8] | Elastic https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html index.max_result_window The maximum value of from + size for searches to this index. Defaults to 10000. Search requests take heap memory and time proportional to from + size and this limits that memory. See Scroll or Search After for a more efficient alternative to raising this. 変更 curl -H "Content-Type: application/json" -XPUT 'https://vpc-xxx-xxxx.ap-northeast-1.es.amazonaws.com/xxxx/_settings' -d ' { "index": { "max_result_window" : "1000000" } }' 確認 curl -X GET "https://vpc-xxx-xxx.ap-northeast-1.es.amazonaws.com/xxxx/_settings?pretty" 結果 [ec2-user@bastin ~]$ curl -H "Content-Type: application/json" -XPUT 'https://vpc-xxx-xxxxx.ap-northeast-1.es.amazonaws.com/xxxxx/_settings' -d ' > { > "index": { > "max_result_window" : "1000000" > } > }' [ec2-user@bastin ~]$ curl -X GET "https://vpc-xx-xx.ap-northeast-1.es.amazonaws.com/xxxxx/_settings?pretty" { "amazon_neptune" : { "settings" : { "index" : { "number_of_shards" : "1", "provided_name" : "xxxxx", "max_result_window" : "1000000", "creation_date" : "1595601039642", "number_of_replicas" : "1", "uuid" : "05kXhekxQ5KUfqyI4_nABw", "version" : { "created" : "7040299" } } } } --- ### ora2pgを使用してOracleからPostgreSQLのスキーマ移行を実施 date: 2020-07-06 url: https://zatoima.github.io/oracle-postgresql-ora2pg-migration.html tags: Oracle, PostgreSQL, DB Migration ora2pgのセットアップ、変換作業の実施。インストール手順はora2pgのサイトを参照。 Instant Client Packageのインストール Instant ClientのrpmダウンロードはOracle社のサイトから。 sudo rpm -ivh oracle-instantclient19.6-basic-19.6.0.0.0-1.x86_64.rpm sudo rpm -ivh oracle-instantclient19.6-devel-19.6.0.0.0-1.x86_64.rpm sudo rpm -ivh oracle-instantclient19.6-jdbc-19.6.0.0.0-1.x86_64.rpm sudo rpm -ivh oracle-instantclient19.6-sqlplus-19.6.0.0.0-1.x86_64.rpm 環境変数の設定 vi .bash_profile ↓下記を追記 export LD_LIBRARY_PATH=/usr/lib/oracle/19.6/client64/lib export ORACLE_HOME=/usr/lib/oracle/19.6/client64/lib source .bash_profile DBD::Oracleのインストール sudo su - export LD_LIBRARY_PATH=/usr/lib/oracle/19.6/client64/lib export ORACLE_HOME=/usr/lib/oracle/19.6/client64/lib yum -y install perl-CPAN yum -y install libyaml-devel yum -y install gcc perl -MCPAN -e shell #全てEnter perl -MCPAN -e 'install DBI' perl -MCPAN -e 'install DBD::Oracle' ora2pgのインストール sudo su - ec2-user sudo yum -y install git git clone https://github.com/darold/ora2pg.git cd ./ora2pg perl Makefile.PL make && make install ora2pgのインストール自体は以上で終了。 ora2pgの初期セッティング mkdir ora2pg ora2pg --project_base ~/ora2pg --init_project migration_test ora2pg.confの設定 ./config配下にora2pg.confが作成されているのでこのファイルを修正する。細かい挙動を制御するパラメータもあるが割愛。 vi ./config/ora2pg.conf # Set Oracle database connection (datasource, user, password) ORACLE_DSN dbi:Oracle:host=xxxxxxxxxxxxx;sid=ora19db;port=1521 ORACLE_USER ikotest ORACLE_PWD oracle # Oracle schema/owner to use SCHEMA ikotest スキーマ定義の全体export実施 ./export_schema.sh 実行後は「reports」、「schema」配下を重点的に確認 ├── config │ └── ora2pg.conf ├── CONSTRAINTS_output.sql ├── data ├── export_schema.sh ├── import_all.sh ├── INDEXES_output.sql ├── reports │ ├── columns.txt │ ├── report.html │ └── tables.txt ├── schema │ ├── dblinks │ ├── directories │ ├── functions │ ├── grants │ ├── mviews │ ├── packages │ ├── partitions │ ├── procedures │ ├── sequences │ ├── synonyms │ │ └── synonym.sql │ ├── tables │ │ ├── CONSTRAINTS_table.sql │ │ ├── INDEXES_table.sql │ │ └── table.sql │ ├── tablespaces │ ├── triggers │ ├── types │ └── views └── sources ├── functions ├── mviews ├── packages ├── partitions ├── procedures ├── triggers ├── types └── views SQL変換 ora2pg -c config/ora2pg.conf -i input.sql -o output.sql -t QUERY --- ### Aurora(PostgreSQL)へのSSL接続について date: 2020-07-02 url: https://zatoima.github.io/aws-aurora-postgresql-ssl-connect.html tags: AWS, Aurora, PostgreSQL 事前準備 https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Security.html SSL 接続ステータスを調べる 拡張機能のインストール create extension sslinfo; SSLの使用有無の確認 select ssl_is_used(); select ssl_cipher(); SSL無しで接続 [ec2-user@bastin ~]$ export PGSSLMODE=disable [ec2-user@bastin ~]$ psql -h aurorapgsqlv1.cluster-xxxxxx.ap-northeast-1.rds.amazonaws.com -U postgres -d postgres psql (11.5, server 11.7) Type "help" for help. postgres=> select ssl_is_used(); ssl_is_used ------------- f (1 row) SSL有りで接続 RDSは作成時にSSL証明書が自動的に用意されており、RDSへの接続は基本的にSSLが有効化されている。ログインプロンプトでもSSLが使用されていることが確認可能。 [ec2-user@bastin ~]$ psql -h aurorapgsqlv1.cluster-xxxxxx.ap-northeast-1.rds.amazonaws.com -U postgres -d postgres psql (11.5, server 11.7) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) Type "help" for help. postgres=> select ssl_is_used(); ssl_is_used ------------- t (1 row) postgres=> select ssl_cipher(); ssl_cipher ----------------------------- ECDHE-RSA-AES256-GCM-SHA384 (1 row) SSL接続を有効化したい場合はrds.force_sslを「0」から「1」に変更する。 なりすまし防止、改ざん防止のために証明書を検証 ルート証明書を取得してなりすまし防止、改ざん防止のための検証を行う必要がある。検証を行う意味としては下記を参照。 SSLって何?意味や仕組みをわかりやすく解説! | さくらのSSL https://ssl.sakura.ad.jp/column/ssl/ 改ざん防止となりすましの防止については、SSLサーバー証明書の「認証局」という組織の存在が重要になります。暗号化自体は認証局が無くても実現可能ですが、認証局はサーバーでもパソコンでもない第三者機関であり、「○○.jpを名乗るこのサイトは本当に○○.jpですよ」と保証してくれる組織です。 認証局が発行する「ルート証明書」というものはパソコンやスマートフォン内に保存され、サーバーから送られてくるSSLサーバー証明書と中間CA証明書が、本当にルート証明書と関連付けられた証明書(認証局が発行した証明書)であるかを検証します。ルート証明書はパソコン本体に入っており、悪意のある第三者が改ざんすることは難しいため、このような仕組みになっています。当然、不正なルート証明書をインストールして不正なSSLサーバー証明書を正当化しようとする悪意のある攻撃も存在します。 証明書の種類によっては「○○.jpとは、株式会社○○が運営しているサイトですよ」と運営組織を保証してくれる場合もあります(OV/EV認証)。銀行のホームページにアクセスして鍵アイコンをクリックすると会社名が表示されるのはEV証明書という特殊なSSLサーバー証明書を利用しているからです。 ルート証明書を取得 wget https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem psql "host=aurorapgsqlv1.cluster-xxxxxx.ap-northeast-1.rds.amazonaws.com sslmode=verify-full sslrootcert=rds-combined-ca-bundle.pem user=postgres dbname=postgres" 検証成功時 psqlの引数としてsslrootcert,sslmodeを指定している。 [ec2-user@bastin ~]$ psql "host=aurorapgsqlv1.cluster-xxxxxx.ap-northeast-1.rds.amazonaws.com sslmode=verify-full sslrootcert=rds-combined-ca-bundle.pem user=postgres dbname=postgres" psql (11.5, server 11.7) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) Type "help" for help. 下記の様に環境変数に設定することでも問題無し。 export PGSSLMODE=verify-full export PGSSLROOTCERT=rds-combined-ca-bundle.pem psql -h aurorapgsqlv1.cluster-xxxxxx.ap-northeast-1.rds.amazonaws.com -U postgres -d postgres 検証失敗時 [ec2-user@bastin ~]$ psql "host=aurorapgsqlv1.cluster-xxxxxx.ap-northeast-1.rds.amazonaws.com sslmode=verify-full sslrootcert=dummy.pem user=postgres dbname=postgres" psql: could not read root certificate file "dummy.pem": no SSL error reported [ec2-user@bastin ~]$ 参考 Amazon Aurora PostgreSQL でのセキュリティ - Amazon Aurora https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Security.html SSL/TLS 証明書の更新 - Amazon Aurora https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/UsingWithRDS.SSL-certificate-rotation.html --- ### IAM認証を使用したAurora(PostgreSQL)への接続 date: 2020-06-28 url: https://zatoima.github.io/aws-aurora-postgresql-iam-connect.html tags: AWS, Aurora, PostgreSQL IAMデータベース認証の有効化 マネージメントコンソール、もしくは下記コマンドで有効化する aws rds modify-db-cluster --db-cluster-identifier aurorapgsqlv1 --apply-immediately --enable-iam-database-authentication IAMデータベース認証が有効になっているか確認 aws rds describe-db-clusters --db-cluster-identifier aurorapgsqlv1 --query 'DBClusters[].[IAMDatabaseAuthenticationEnabled]' --output table IAMデータベース認証用のPostgreSQLユーザを作成 rds_iamは固定。 CREATE USER iam_user WITH LOGIN; grant rds_iam to iam_user; IAMポリシーを作成 AWS CLIから作成するのでiam_rds_connect.jsonを作成 cat << EOF > iam_rds_connect.json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "rds-db:connect" ], "Resource": [ "arn:aws:rds-db:ap-northeast-1:xxxxxxxxxxx:dbuser:cluster-ALPQLYUXTQZEQ7M7F5UBRC7WTU/iam_user" ] } ] } EOF Resource箇所でリージョン、アカウントID、クラスタID、PostgreSQLのユーザ名を指定。 クラスタIDは下記CLIで確認が可能。 aws rds describe-db-clusters --db-cluster-identifier aurorapgsqlv1 --query "DBClusters[0].[DbClusterResourceId]" IAMポリシーを作成 aws iam create-policy --policy-name iam_rds_connect --policy-document file://iam_rds_connect.json [ec2-user@bastin ~]$ aws iam create-policy --policy-name iam_rds_connect --policy-document file://iam_rds_connect.json { "Policy": { "PolicyName": "iam_rds_connect", "PermissionsBoundaryUsageCount": 0, "CreateDate": "2020-06-21T10:50:56Z", "AttachmentCount": 0, "IsAttachable": true, "PolicyId": "ANPAR23YLZYEHAKGAXPDT", "DefaultVersionId": "v1", "Path": "/", "Arn": "arn:aws:iam::xxxxxxxxxxx:policy/iam_rds_connect", "UpdateDate": "2020-06-21T10:50:56Z" } } [ec2-user@bastin ~]$ IAMユーザがAdministratorAccessのように強い権限を所持していたらここまででOKで、権限を絞っているのであればIAM ユーザーまたはロールへの IAM ポリシーのアタッチが必要となる。 IAM データベースアクセス用の IAM ポリシーの作成と使用 - Amazon Aurora https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/UsingWithRDS.IAMDBAuth.IAMPolicy.html IAMデータベースを使用したAurora PostgreSQLへの接続 認証情報は aws rds generate-db-auth-tokenで取得可能。PostgreSQLへの接続時には環境変数のPGPASSWORDに変数として入れる。認証トークンは数百の文字で構成されて長いので、コピペしてログインよりもこちらの方法の方がスマート。 export PGPASSWORD=`aws --region ap-northeast-1 rds generate-db-auth-token --hostname aurorapgsqlv1.cluster-xxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com --port 5432 --username iam_user` psql -h aurorapgsqlv1.cluster-xxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -U iam_user -d postgres 成功パターン [ec2-user@bastin ~]$ export PGPASSWORD=`aws --region ap-northeast-1 rds generate-db-auth-token --hostname aurorapgsqlv1.cluster-xxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com --port 5432 --username iam_user` [ec2-user@bastin ~]$ psql -h aurorapgsqlv1.cluster-xxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -U iam_user -d postgres psql (11.5, server 11.7) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) Type "help" for help. postgres=> select version(); version ----------------------------------------------------------------------------- PostgreSQL 11.7 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.9.3, 64-bit (1 row) postgres=> select aurora_version(); aurora_version ---------------- 3.2.1 (1 row) 失敗パターン [ec2-user@bastin ~]$ psql -h aurorapgsqlv1.cluster-xxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -U iam_user -d postgres psql: FATAL: password authentication failed for user "iam_user" FATAL: password authentication failed for user "iam_user" 最後に RDS(Aurora含む)への接続時の認証は他にもSystems Manager パラメータストアやSecrets Manager等、色々あってどれを使うべきか迷う、、。IAM認証に関してその他の注意事項等はマニュアルを参照。データベースクラスターの 1 秒あたりの最大接続数は、クラスタータイプとワークロードに応じて制限される場合があります。と記載あるのが個人的には気になるところ。 https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/UsingWithRDS.IAMDBAuth.html IAM データベース認証の MySQL の制限事項 IAM データベース認証の PostgreSQL の制限事項 --- ### Systems Managerのパラメータストアを使用してAurora PostgreSQLのパスワードを管理 date: 2020-06-25 url: https://zatoima.github.io/aws-aurora-postgresql-parameter-store-connect.html tags: AWS, Aurora, PostgreSQL 事前準備 はじめに Aurora PostgreSQL側にユーザ名testuser、パスワードp@sstestで作成。 CREATE ROLE testuser WITH LOGIN PASSWORD 'p@sstest'; psqlでログインする場合には環境変数に設定して下記のように接続。パスワードをどこかに持つ必要があってセキュアな状態とは言えない。。。 [ec2-user@bastin ~]$ export PGUSER=testuser [ec2-user@bastin ~]$ export PGPASSWORD=xxxxx [ec2-user@bastin ~]$ psql -h aurorapgsqlv1.cluster-xxxxxx.ap-northeast-1.rds.amazonaws.com -d postgres psql (11.5, server 11.7) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) Type "help" for help. postgres=> \conninfo You are connected to database "postgres" as user "testuser" on host "aurorapgsqlv1.cluster-xxxxxx.ap-northeast-1.rds.amazonaws.com" at port "5432". SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) Systems Managerにパラメータを格納 2つのパラメータを格納してみる。useridは平文(String)でpasswordはSecureStringで格納。 aws ssm put-parameter --name 'pgsql.connect.userid' --type 'String' --value 'testuser' aws ssm put-parameter --name 'pgsql.connect.password' --type 'SecureString' --value 'p@sstest' パラメータを取得してみる。pgsql.connect.useridを取得する。 [ec2-user@bastin ~]$ aws ssm get-parameters --name 'pgsql.connect.userid' { "InvalidParameters": [], "Parameters": [ { "Name": "pgsql.connect.userid", "DataType": "text", "LastModifiedDate": 1592740003.175, "Value": "testuser", "Version": 1, "Type": "String", "ARN": "arn:aws:ssm:ap-northeast-1:xxxxxx:parameter/pgsql.connect.userid" } ] } 次にpgsql.connect.passwordを取得。SecureStringで格納したパラメータについては--with-decryptionを付与してコマンドを実行する必要がある。このオプションがないと暗号化された状態でvalueが出力される。(内部的にはKMSが使用されており、KMSの使用権限を持っていなければ復号化が出来ない。) [ec2-user@bastin ~]$ aws ssm get-parameters --name 'pgsql.connect.password' { "InvalidParameters": [], "Parameters": [ { "Name": "pgsql.connect.password", "DataType": "text", "LastModifiedDate": 1592740007.647, "Value": "AQICAHimGbBDsXKAeEMDoI4Kw/rpZAgukrSwYmqXyAKBupBtkwFYzzG2rJ2dnIePkkrTPZdsAAAAZjBkBgkqhkiG9w0BBwagVzBVAgEAMFAGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMoiJHw/NeYmZj35gYAgEQgCNgQlRcIz7EgkLxyHV4weHFwONVhdTI9m3OilaP2ikVHLbqQg==", "Version": 1, "Type": "SecureString", "ARN": "arn:aws:ssm:ap-northeast-1:xxxxxx:parameter/pgsql.connect.password" } ] } [ec2-user@bastin ~]$ [ec2-user@bastin ~]$ aws ssm get-parameters --name 'pgsql.connect.password' --with-decryption { "InvalidParameters": [], "Parameters": [ { "Name": "pgsql.connect.password", "DataType": "text", "LastModifiedDate": 1592740007.647, "Value": "p@sstest", "Version": 1, "Type": "SecureString", "ARN": "arn:aws:ssm:ap-northeast-1:xxxxxx:parameter/pgsql.connect.password" } ] } Aurora(PostgreSQL)へ接続 aws ssm get-parametersコマンドを使用することでパスワードを直書きするというセキュリティ的なリスクが無くなる。 [ec2-user@bastin ~]$ export PGUSER=$(aws ssm get-parameters --name 'pgsql.connect.userid' | jq -r '.Parameters[].Value') [ec2-user@bastin ~]$ export PGPASSWORD=$(aws ssm get-parameters --name 'pgsql.connect.password' --with-decryption | jq -r '.Parameters[].Value') [ec2-user@bastin ~]$ [ec2-user@bastin ~]$ echo $PGUSER testuser [ec2-user@bastin ~]$ echo $PGPASSWORD p@sstest [ec2-user@bastin ~]$ [ec2-user@bastin ~]$ psql -h aurorapgsqlv1.cluster-xxxxxx.ap-northeast-1.rds.amazonaws.com -d postgres psql (11.5, server 11.7) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) Type "help" for help. postgres=> \conninfo You are connected to database "postgres" as user "testuser" on host "aurorapgsqlv1.cluster-xxxxxx.ap-northeast-1.rds.amazonaws.com" at port "5432". SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) postgres=> 次は同じような使い方が出来るAWS Secrets Managerを触ってみる。 その他参考情報 任意のパラメータを格納できる EC2 Systems Manager「パラメータストア」を試したら便利だった - kakakakakku blog https://kakakakakku.hatenablog.com/entry/2017/06/10/181603 AWSのParameter StoreとSecrets Manager、結局どちらを使えばいいのか?比較 - Qiita https://qiita.com/tomoya_oka/items/a3dd44879eea0d1e3ef5 --- ### OracleとPostgreSQL(+Redshift)のchar、varcharのバイトと文字数の違い date: 2020-06-24 url: https://zatoima.github.io/oracle-postgresql-char-varchar-byte.html tags: Oracle, PostgreSQL, DB Migration charとvarcharの引数指定はOracleはバイト数である一方PostgreSQLは文字数となる。UTF8環境のOracleでchar(10)とした場合は3文字しか格納出来ない。一方、PostgreSQLでchar(10)と設定した場合は、10文字格納出来る。ora2pgやSCT(schema conversion tool)ではこの非互換は変換されないので注意が必要。 Oracle/PostgreSQL共通 create table chartest(a char(10)); PostgreSQL char(10)の列に全角10文字を格納し、長さとバイト数を確認。 postgres> insert into chartest values('123456789あ'); INSERT 0 1 Time: 0.004s postgres> SELECT LENGTH(a) from chartest; +----------+ | length | |----------| | 10 | +----------+ SELECT 1 Time: 0.017s postgres> SELECT OCTET_LENGTH(a) from chartest; +----------------+ | octet_length | |----------------| | 30 | +----------------+ SELECT 1 Time: 0.017s #文字数オーバーなパターン postgres> insert into chartest values('123456789あい'); value too long for type character(10) Time: 0.004s postgres> https://www.postgresql.jp/document/11/html/datatype-character.html SQLは2つの主要な文字データ型を定義しています。 character varying(*n*)とcharacter(*n*)です。 ここで*nは正の整数です。 これらのデータ型は2つともn*文字長(バイト数ではなく)までの文字列を保存できます。 Oracle 同様に10バイト分のデータを入れて確認。 SQL> insert into chartest values('123'); 1 row inserted. SQL> SELECT LENGTHB(a) from chartest; LENGTHB(A) _____________ 10 SQL> SELECT LENGTH(a) from chartest; LENGTH(A) ____________ 4 SQL> insert into chartest values('1234'); Error starting at line : 1 in command - insert into chartest values('1234') Error report - ORA-12899: value too large for column "ADMIN"."CHARTEST"."A" (actual: 12, maximum: 10) https://docs.oracle.com/cd/F19136_01/sqlrf/Data-Types.html#GUID-7B72E154-677A-4342-A1EA-C74C1EA928E6 Oracleの組込みデータ型 追記:Redshiftの場合 PostgreSQLベースのRedshiftはPostgreSQLと同じで文字数かー、と思っていてマニュアルを念の為に確認してみるとバイト単位だったので注意。 https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_Character_types.html CHAR および VARCHAR のデータ型は、文字単位でなくバイト単位で定義されます。CHAR 列にはシングルバイト文字のみを含めることができます。したがって、CHAR(10) 列には、最大 10 バイト長の文字列を含めることができます。VARCHAR にはマルチバイト文字 (1 文字あたり最大で 4 バイトまで) を含めることができます。例えば、VARCHAR(12) 列には、シングルバイト文字なら 12 個、2 バイト文字なら 6 個、3 バイト文字なら 4 個、4 バイト文字なら 3 個含めることができます。 --- ### ora2pgを使用したOracleからPostgreSQLへの変換結果 date: 2020-06-21 url: https://zatoima.github.io/aws-ora2pg-oracle-to-aurora-postgresql-conversion.html tags: AWS, SCT, Oracle, PostgreSQL, DB Migration 以前にAWS SCTで実施したOracleからAurora(PostgreSQL)への変換を今度はora2pgで実行してみた。 AWS Schema Conversion Toolを使用したOracleからAurora(PostgreSQL)への変換結果 | my opinion is my own https://zatoima.github.io/aws-sct-oracle-to-aurora-postgresql-conversion.html Oracle CREATE文 CREATE TABLE "DATATYPES"( "BFILE" BFILE, "BINARY_FLOAT" BINARY_FLOAT, "BINARY_DOUBLE" BINARY_DOUBLE, "BLOB" BLOB, "CHAR" CHAR(10 BYTE), "CHARACTER" CHAR(10 BYTE), "CLOB" CLOB, "NCLOB" NCLOB, "DATE" DATE, "DECIMAL" NUMBER(3,2), "DEC" NUMBER(3,2), "DOUBLE_PRECISION" FLOAT(126), "FLOAT" FLOAT(3), "INTEGER" NUMBER(*,0), "INT" NUMBER(*,0), "INTERVAL_YEAR" INTERVAL YEAR(4) TO MONTH, "INTERVAL_DAY" INTERVAL DAY(4) TO SECOND(4), "LONG" LONG, "NCHAR" NCHAR(10), "NCHAR_VARYING" NVARCHAR2(10), "NUMBER" NUMBER(9,9), "NUMBER1" NUMBER(9,0), "NUMBER(*)" NUMBER, "NUMERIC" NUMBER(9,9), "NVARCHAR2" NVARCHAR2(10), "RAW" RAW(10), "REAL" FLOAT(63), "ROW_ID" ROWID, "SMALLINT" NUMBER(*,0), "TIMESTAMP" TIMESTAMP(5), "TIMESTAMP WITH TIME ZONE" TIMESTAMP(5) WITH TIME ZONE, "UROWID" UROWID(10), "VARCHAR" VARCHAR2(10 BYTE), "VARCHAR2" VARCHAR2(10 BYTE), "XMLTYPE" "PUBLIC"."XMLTYPE" ); テーブル定義 SQL> desc DATATYPES; Name Null? Type ----------------------------------------- -------- ---------------------------- BFILE BINARY FILE LOB BINARY_FLOAT BINARY_FLOAT BINARY_DOUBLE BINARY_DOUBLE BLOB BLOB CHAR CHAR(10) CHARACTER CHAR(10) CLOB CLOB NCLOB NCLOB DATE DATE DECIMAL NUMBER(3,2) DEC NUMBER(3,2) DOUBLE_PRECISION FLOAT(126) FLOAT FLOAT(3) INTEGER NUMBER(38) INT NUMBER(38) INTERVAL_YEAR INTERVAL YEAR(4) TO MONTH INTERVAL_DAY INTERVAL DAY(4) TO SECOND(4) LONG LONG NCHAR NCHAR(10) NCHAR_VARYING NVARCHAR2(10) NUMBER NUMBER(9,9) NUMBER1 NUMBER(9) NUMBER(* ) NUMBER NUMERIC NUMBER(9,9) NVARCHAR2 NVARCHAR2(10) RAW RAW(10) REAL FLOAT(63) ROW_ID ROWID SMALLINT NUMBER(38) TIMESTAMP TIMESTAMP(5) TIMESTAMP WITH TIME ZONE TIMESTAMP(5) WITH TIME ZONE UROWID ROWID VARCHAR VARCHAR2(10) VARCHAR2 VARCHAR2(10) XMLTYPE PUBLIC.XMLTYPE STORAGE BINARY PostgreSQL CREATE文 CREATE TABLE datatypes ( bfile bytea, binary_float double precision, binary_double double precision, blob bytea, char char(10), character char(10), clob text, nclob text, date timestamp, decimal real, dec real, double_precision double precision, float double precision, integer numeric(38), int numeric(38), interval_year INTERVAL YEAR TO MONTH, interval_day INTERVAL DAY TO SECOND(4), long text, nchar char(10), nchar_varying varchar(10), number double precision, number1 integer, "number(*)" bigint, numeric double precision, nvarchar2 varchar(10), raw bytea, real double precision, row_id oid, smallint numeric(38), timestamp timestamp, "timestamp with time zone" timestamp with time zone, urowid oid, varchar varchar(10), varchar2 varchar(10), xmltype xml ) ; テーブル定義 postgres> \d datatypes +--------------------------+-----------------------------+-------------+ | Column | Type | Modifiers | |--------------------------+-----------------------------+-------------| | bfile | bytea | | | binary_float | double precision | | | binary_double | double precision | | | blob | bytea | | | char | character(10) | | | character | character(10) | | | clob | text | | | nclob | text | | | date | timestamp without time zone | | | decimal | real | | | dec | real | | | double_precision | double precision | | | float | double precision | | | integer | numeric(38,0) | | | int | numeric(38,0) | | | interval_year | interval year to month | | | interval_day | interval day to second(4) | | | long | text | | | nchar | character(10) | | | nchar_varying | character varying(10) | | | number | double precision | | | number1 | integer | | | number(*) | bigint | | | numeric | double precision | | | nvarchar2 | character varying(10) | | | raw | bytea | | | real | double precision | | | row_id | oid | | | smallint | numeric(38,0) | | | timestamp | timestamp without time zone | | | timestamp with time zone | timestamp with time zone | | | urowid | oid | | | varchar | character varying(10) | | | varchar2 | character varying(10) | | | xmltype | xml | | +--------------------------+-----------------------------+-------------+ OracleとPostgreSQLを対比した結果は次の通り。一部SCTとora2pgで異なる結果が出た。SCTは下記を参照。 AWS Schema Conversion Toolを使用したOracleからAurora(PostgreSQL)への変換結果 | my opinion is my own https://zatoima.github.io/aws-sct-oracle-to-aurora-postgresql-conversion.html OracleとPostgreSQLの対比一覧 No. Oracle (※descの結果) PostgreSQL (\d メタコマンド結果) 1 BINARY FILE LOB bytea 2 BINARY_FLOAT double precision 3 BINARY_DOUBLE double precision 4 BLOB bytea 5 CHAR(10) character(10) 6 CHAR(10) character(10) 7 CLOB text 8 NCLOB text 9 DATE timestamp without time zone 10 NUMBER(3,2) real 11 NUMBER(3,2) real 12 FLOAT(126) double precision 13 FLOAT(3) double precision 14 NUMBER(38) numeric(38,0) 15 NUMBER(38) numeric(38,0) 16 INTERVAL YEAR(4) TO MONTH interval year to month 17 INTERVAL DAY(4) TO SECOND(4) interval day to second(4) 18 LONG text 19 NCHAR(10) character(10) 20 NVARCHAR2(10) character varying(10) 21 NUMBER(9,9) double precision 22 NUMBER(9) integer 23 NUMBER bigint 24 NUMBER(9,9) double precision 25 NVARCHAR2(10) character varying(10) 26 RAW(10) bytea 27 FLOAT(63) double precision 28 ROWID oid 29 NUMBER(38) numeric(38,0) 30 TIMESTAMP(5) timestamp without time zone 31 TIMESTAMP(5) WITH TIME ZONE timestamp with time zone 32 ROWID oid 33 VARCHAR2(10) character varying(10) 34 VARCHAR2(10) character varying(10) 35 PUBLIC.XMLTYPE STORAGE BINARY xml --- ### PostgreSQLでja_JP.UTF-8のデータベース作成時のlocaleエラー date: 2020-06-17 url: https://zatoima.github.io/postgresql-create-database-locale-error.html tags: PostgreSQL PostgreSQL上でja_JP.UTF-8 を指定してデータベースを指定した場合にエラー発生 postgres=# CREATE DATABASE locale_jp_utf8 postgres-# TEMPLATE template0 ENCODING 'UTF-8' postgres-# LC_COLLATE 'ja_JP.UTF-8' LC_CTYPE 'ja_JP.UTF-8'; ERROR: invalid locale name: "ja_JP.UTF-8" OS上のlocaleを確認してみたらja_JP.UTF-8がない。 [postgres@pgsql ~]$ locale -a C C.utf8 en_AG en_AU en_AU.utf8 en_BW en_BW.utf8 en_CA en_CA.utf8 en_DK en_DK.utf8 en_GB en_GB.iso885915 en_GB.utf8 en_HK en_HK.utf8 en_IE en_IE@euro en_IE.utf8 en_IL en_IN en_NG en_NZ en_NZ.utf8 en_PH en_PH.utf8 en_SC.utf8 en_SG en_SG.utf8 en_US en_US.iso885915 en_US.utf8 en_ZA en_ZA.utf8 en_ZM en_ZW en_ZW.utf8 POSIX ja_JP.UTF-8をセットアップしようとするとcharacter map fileが見つからないというエラーが発生。 [postgres@pgsql ~]$ sudo localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8 [error] character map file `UTF-8' not found: No such file or directory [error] default character map file `ANSI_X3.4-1968' not found: No such file or directory [postgres@pgsql ~]$ glibc-locale-sourceとglibc-langpack-en をインストール後に再実行 [postgres@pgsql ~]$ sudo yum -y install glibc-locale-source glibc-langpack-en [postgres@pgsql ~]$ sudo localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8 [error] character map file `UTF-8' not found: No such file or directory [error] default character map file `ANSI_X3.4-1968' not found: No such file or directory locale -aで確認 [postgres@pgsql ~]$ locale -a C C.utf8 en_AG en_AU en_AU.utf8 en_BW en_BW.utf8 en_CA en_CA.utf8 en_DK en_DK.utf8 en_GB en_GB.iso885915 en_GB.utf8 en_HK en_HK.utf8 en_IE en_IE@euro en_IE.utf8 en_IL en_IN en_NG en_NZ en_NZ.utf8 en_PH en_PH.utf8 en_SC.utf8 en_SG en_SG.utf8 en_US en_US.iso885915 en_US.utf8 en_ZA en_ZA.utf8 en_ZM en_ZW en_ZW.utf8 ja_JP.utf8 POSIX この状態であればPostgreSQL上でのデータベース作成が成功する。※PostgreSQLの再起動必要 postgres=# CREATE DATABASE locale_us_utf8 postgres-# TEMPLATE template0 ENCODING 'UTF-8' postgres-# LC_COLLATE 'en_US.UTF-8' LC_CTYPE 'en_US.UTF-8'; CREATE DATABASE postgres=# --- ### PostgreSQLのpg_rmanを使用してバックアップ/リカバリを行う date: 2020-06-15 url: https://zatoima.github.io/postgresql-pg_rman-backup-recovery.html tags: PostgreSQL pg_rmanの概要 pg_rmanの手順メモ。rmanと名前についている通り、Oracle の Recovery Managerを意識した機能です。標準機能では使用できない増分バックアップが出来ることでバックアップの短縮に繋がるはず。 全体バックアップに加え、増分バックアップが可能 バックアップの圧縮が可能 バックアップの世代管理やバックアップ一覧を表示できる バックアップの対象はデータベースクラスタの他にアーカイブログ、サーバログが含めることができる タイムライン指定、リカバリしたい日付時刻指定が可能 データベースクラスタ外のテーブルスペースを含めたバックアップが可能 pg_rmanのインストール 下記のgithubのリポジトリから最新のバージョンをインストールします。 Releases · ossc-db/pg_rman https://github.com/ossc-db/pg_rman/releases sudo wget https://github.com/ossc-db/pg_rman/releases/download/V1.3.9/pg_rman-1.3.9-1.pg10.rhel7.x86_64.rpm sudo rpm -ivh pg_rman-1.3.9-1.pg10.rhel7.x86_64.rpm [postgres@postdb ~]$ pg_rman --help pg_rman manage backup/recovery of PostgreSQL database. Usage: pg_rman OPTION init pg_rman OPTION backup pg_rman OPTION restore pg_rman OPTION show [DATE] pg_rman OPTION show detail [DATE] pg_rman OPTION validate [DATE] pg_rman OPTION delete DATE pg_rman OPTION purge Common Options: -D, --pgdata=PATH location of the database storage area -A, --arclog-path=PATH location of archive WAL storage area -S, --srvlog-path=PATH location of server log storage area -B, --backup-path=PATH location of the backup storage area -c, --check show what would have been done -v, --verbose show what detail messages -P, --progress show progress of processed files Backup options: -b, --backup-mode=MODE full, incremental, or archive -s, --with-serverlog also backup server log files -Z, --compress-data compress data backup with zlib -C, --smooth-checkpoint do smooth checkpoint before backup -F, --full-backup-on-error switch to full backup mode if pg_rman cannot find validate full backup on current timeline NOTE: this option is only used in --backup-mode=incremental or archive. --keep-data-generations=NUM keep NUM generations of full data backup --keep-data-days=NUM keep enough data backup to recover to N days ago --keep-arclog-files=NUM keep NUM of archived WAL --keep-arclog-days=DAY keep archived WAL modified in DAY days --keep-srvlog-files=NUM keep NUM of serverlogs --keep-srvlog-days=DAY keep serverlog modified in DAY days --standby-host=HOSTNAME standby host when taking backup from standby --standby-port=PORT standby port when taking backup from standby Restore options: --recovery-target-time time stamp up to which recovery will proceed --recovery-target-xid transaction ID up to which recovery will proceed --recovery-target-inclusive whether we stop just after the recovery target --recovery-target-timeline recovering into a particular timeline --hard-copy copying archivelog not symbolic link Catalog options: -a, --show-all show deleted backup too Delete options: -f, --force forcibly delete backup older than given DATE Connection options: -d, --dbname=DBNAME database to connect -h, --host=HOSTNAME database server host or socket directory -p, --port=PORT database server port -U, --username=USERNAME user name to connect as -w, --no-password never prompt for password -W, --password force password prompt Generic options: -q, --quiet don't show any INFO or DEBUG messages --debug show DEBUG messages --help show this help, then exit --version output version information, then exit Read the website for details. <http://github.com/ossc-db/pg_rman> Report bugs to <http://github.com/ossc-db/pg_rman/issues>. [postgres@postdb ~]$ postgresql.confの設定 archive_mode = on archive_command = 'cp %p /var/lib/pgsql/10/data/pg_wal/archive/%f' wal_level = archive log_directory = 'pg_log' 環境変数編集 BACKUP_PATHを下記の通りとします。 $ export BACKUP_PATH=/var/lib/pgsql/pg_rman_backup バックアップカタログの初期化 [postgres@postdb ~]$ pg_rman init INFO: ARCLOG_PATH is set to '/var/lib/pgsql/10/data/pg_wal/archive' INFO: SRVLOG_PATH is set to '/var/lib/pgsql/10/data/log' [postgres@postdb ~]$ フルバックアップの取得 [postgres@postdb ~]$ pg_rman init INFO: ARCLOG_PATH is set to '/var/lib/pgsql/10/data/pg_wal/archive' INFO: SRVLOG_PATH is set to '/var/lib/pgsql/10/data/log' [postgres@postdb ~]$ [postgres@postdb ~]$ [postgres@postdb ~]$ pg_rman backup --backup-mode=full INFO: copying database files INFO: copying archived WAL files INFO: backup complete INFO: Please execute 'pg_rman validate' to verify the files are correctly copied. [postgres@postdb ~]$ バックアップの検証 validateを実施しないとリストア出来ない。バックアップ後すぐに実施するのが良さそう。 [postgres@postdb ~]$ pg_rman validate INFO: validate: "2020-03-04 12:55:57" backup and archive log files by CRC INFO: backup "2020-03-04 12:55:57" is valid [postgres@postdb ~]$ バックアップ後のディレクトリ状態 cd /var/lib/pgsql/pg_rman_backup ls -l 増分バックアップの実施 [postgres@postdb ~]$ pg_rman backup --backup-mode=incremental --with-serverlog INFO: copying database files INFO: copying archived WAL files INFO: copying server log files INFO: backup complete INFO: Please execute 'pg_rman validate' to verify the files are correctly copied. [postgres@postdb ~]$ pg_rman validate INFO: validate: "2020-03-04 12:58:38" backup, archive log files and server log files by CRC INFO: backup "2020-03-04 12:58:38" is valid [postgres@postdb ~]$ バックアップ後のディレクトリ状態 cd /var/lib/pgsql/pg_rman_backup ls -l バックアップの表示 [postgres@postdb ~]$ pg_rman show ===================================================================== StartTime EndTime Mode Size TLI Status ===================================================================== 2020-03-04 12:58:38 2020-03-04 12:58:41 INCR 42MB 1 OK 2020-03-04 12:55:57 2020-03-04 12:56:15 FULL 1078MB 1 OK [postgres@postdb ~]$ リストア前のDBの停止 [postgres@postdb ~]$ pg_ctl stop waiting for server to shut down.... done server stopped [postgres@postdb ~]$ DBの破壊 雑にDBを破損させました。 [postgres@postdb base]$ pwd /var/lib/pgsql/10/data/base [postgres@postdb base]$ ls -l total 0 [postgres@postdb base]$ [postgres@postdb base]$ psql psql: FATAL: database "postgres" does not exist DETAIL: The database subdirectory "base/13865" is missing. [postgres@postdb base]$ 前回バックアップ時点の最新までリストア [postgres@postdb ~]$ pg_rman restore INFO: the recovery target timeline ID is not given INFO: use timeline ID of current database cluster as recovery target: 1 INFO: calculating timeline branches to be used to recovery target point INFO: searching latest full backup which can be used as restore start point INFO: found the full backup can be used as base in recovery: "2020-03-04 12:55:57" INFO: copying online WAL files and server log files INFO: clearing restore destination INFO: validate: "2020-03-04 12:55:57" backup and archive log files by SIZE INFO: backup "2020-03-04 12:55:57" is valid INFO: restoring database files from the full mode backup "2020-03-04 12:55:57" INFO: searching incremental backup to be restored INFO: validate: "2020-03-04 12:58:38" backup, archive log files and server log files by SIZE INFO: backup "2020-03-04 12:58:38" is valid INFO: restoring database files from the incremental mode backup "2020-03-04 12:58:38" INFO: searching backup which contained archived WAL files to be restored INFO: backup "2020-03-04 12:58:38" is valid INFO: restoring WAL files from backup "2020-03-04 12:58:38" INFO: restoring online WAL files and server log files INFO: generating recovery.conf INFO: restore complete HINT: Recovery will start automatically when the PostgreSQL server is started. [postgres@postdb ~]$ [postgres@postdb ~]$ pg_ctl status pg_ctl: no server running pg_ctl start時のログ・ファイルを確認したところリカバリ処理が走っている。2020-03-04 12:58:40.102645+00時点まで戻ったことが確認出来る。 [postgres@postdb log]$ cat postgresql-20200304.log [2020-03-04 13:05:24 UTC] 17807[1] LOG: database system was interrupted; last known up at 2020-03-04 12:58:38 UTC [2020-03-04 13:05:24 UTC] 17807[2] LOG: starting archive recovery [2020-03-04 13:05:24 UTC] 17807[3] LOG: restored log file "000000010000000000000047" from archive [2020-03-04 13:05:24 UTC] 17807[4] LOG: redo starts at 0/47000028 [2020-03-04 13:05:24 UTC] 17807[5] LOG: consistent recovery state reached at 0/470000F8 [2020-03-04 13:05:24 UTC] 17805[6] LOG: database system is ready to accept read only connections [2020-03-04 13:05:24 UTC] 17807[6] LOG: restored log file "000000010000000000000048" from archive [2020-03-04 13:05:25 UTC] 17807[7] LOG: restored log file "000000010000000000000049" from archive [2020-03-04 13:05:25 UTC] 17807[8] LOG: restored log file "00000001000000000000004A" from archive cp: cannot stat ‘/var/lib/pgsql/10/data/pg_wal/archive/00000001000000000000004B’: No such file or directory [2020-03-04 13:05:25 UTC] 17807[9] LOG: invalid record length at 0/4B000098: wanted 24, got 0 [2020-03-04 13:05:25 UTC] 17807[10] LOG: redo done at 0/4B000028 [2020-03-04 13:05:25 UTC] 17807[11] LOG: last completed transaction was at log time 2020-03-04 12:58:40.102645+00 物理ファイルもリストアされている。 [postgres@postdb base]$ pwd /var/lib/pgsql/10/data/base [postgres@postdb base]$ ls -l total 60 drwx------ 2 postgres postgres 8192 Mar 4 13:03 1 drwx------ 2 postgres postgres 8192 Mar 4 13:03 13864 drwx------ 2 postgres postgres 8192 Mar 4 13:03 13865 drwx------ 2 postgres postgres 8192 Mar 4 13:03 16392 drwx------ 2 postgres postgres 8192 Mar 4 13:03 16456 [postgres@postdb base]$ find . | more . ./1 ./1/18121 ./1/18121_fsm ./1/18121_vm ./1/18124 ./1/18124_fsm ./1/18124_vm ./1/18126 ./1/18127 ./1/18128 ./1/18128_fsm ./1/18128_vm ./1/18131 PITR 特定時点まで戻す場合は下記を実行する、 pg_rman restore --recovery-target-time '2020-03-04 22:00:00' pg_rmanのコマンド・オプション Usage pg_rman https://ossc-db.github.io/pg_rman/index-ja.html 参考 pg_rman (PostgreSQL のバックアップ/リストア管理ツール) https://www.sraoss.co.jp/tech-blog/pgsql/pg_rman/ --- ### Oracle PL/SQLでバイナリデータ・ファイルをBLOBに挿入する date: 2020-06-13 url: https://zatoima.github.io/oracle-plsql-blob-insert.html tags: PostgreSQL ディレクトリ作成 mkdir -p /home/oracle/lobdir テスト用のファイル作成 バイナリデータというわけではないが、適当なファイルを作成する。 dd if=/dev/zero of=/home/oracle/oradir/10M.dummy bs=1M count=10 ディレクトリオブジェクトの作成 drop directory oradir; CREATE DIRECTORY ORADIR AS '/home/oracle/oradir'; シーケンス作成(Primary key用) primary keyとして使用するため、シーケンスを作成。 drop sequence oraseq1; create sequence oraseq1 start with 1 increment by 1 cache 20; テーブル作成 primary keyであるid、ファイル名を挿入するname、BLOBのサイズを格納するlobsize、blobデータを格納するblobdataで構成。 drop table BLOB_TBL; CREATE TABLE BLOB_TBL ( id number, name VARCHAR2(100), lobsize VARCHAR2(100), blobdata BLOB, CONSTRAINT BLOB_TBL_PK PRIMARY KEY (id) ) LOB (blobdata) STORE AS BASICFILE; プロシージャ作成 BLOBのサイズをカラムに挿入することで各ファイルのサイズがわかるようにした。 drop PROCEDURE LOAD_BLOB_TBL; CREATE PROCEDURE LOAD_BLOB_TBL(filename VARCHAR2) AS bfileloc BFILE; blobloc BLOB; BEGIN bfileloc := BFILENAME('ORADIR', filename); INSERT INTO BLOB_TBL VALUES(oraseq1.nextval,filename, DBMS_LOB.GETLENGTH(bfileloc), EMPTY_BLOB()) RETURN blobdata INTO blobloc; DBMS_LOB.FILEOPEN(bfileloc, DBMS_LOB.FILE_READONLY); DBMS_LOB.LOADFROMFILE(blobloc, bfileloc, DBMS_LOB.GETLENGTH(bfileloc)); DBMS_LOB.FILECLOSE(bfileloc); COMMIT; dbms_output.put_line ( 'Blob Size : ' || DBMS_LOB.GETLENGTH(bfileloc) || ' Bytes' ); END; / プロシージャテスト EXEC LOAD_BLOB_TBL('10M.dummy'); 結果確認 set pages 2000 lin 2000 col name for a20 col lobsize for a20 select * from blob_tbl; 参考 ファイルをBLOBとしてテーブルに読み込む - とあるSIerの憂鬱 https://incarose86.hatenadiary.org/entry/20140720/1405875714 --- ### EC2からEFSをマウントして使ってみる date: 2020-06-11 url: https://zatoima.github.io/aws-efs-ec2-mount.html tags: AWS, EC2, EFS 既にマネージメントコンソール側にEFSを作成しているとして、、、、、 amazon-efs-utilsのインストール sudo yum -y install amazon-efs-utils マウント用のディレクトリ作成 sudo mkdir /mnt/efs sudo chown ec2-user:ec2-user /mnt/efs sudo mount -t efs fs-xxxxx:/ /mnt/efs echo $? ファイルシステムIDをfs-xxxxxに指定 dfで確認してEFSがマウント出来ていることを確認 [ec2-user@bastin ~]$ df -h Filesystem Size Used Avail Use% Mounted on devtmpfs 475M 0 475M 0% /dev tmpfs 492M 0 492M 0% /dev/shm tmpfs 492M 436K 492M 1% /run tmpfs 492M 0 492M 0% /sys/fs/cgroup /dev/xvda1 20G 6.5G 14G 33% / tmpfs 99M 0 99M 0% /run/user/1000 fs-xxxxxx.efs.ap-northeast-1.amazonaws.com:/ 8.0E 0 8.0E 0% /mnt/efs [ec2-user@bastin ~]$ 再起動時にマウントするために/etc/fstabに追加 fs-xxxxx:/ /mnt/efs efs defaults,_netdev 0 0 性能簡易測定(ddコマンド) [ec2-user@bastin efs]$ dd if=/dev/zero of=/mnt/efs/write.txt ibs=4k obs=4k count=2048 2048+0 records in 2048+0 records out 8388608 bytes (8.4 MB) copied, 1.34538 s, 6.2 MB/s fioコマンド sudo yum install -y fio fio --version block size が 4kの場合 -- sequencial read fio -filename=/mnt/efs/fio_test -direct=1 -rw=read -bs=4k -size=2G -numjobs=64 -runtime=10 -group_reporting -name=file1 -- ramdom read fio -filename=/mnt/efs/fio_test -direct=1 -rw=randread -bs=4k -size=2G -numjobs=64 -runtime=10 -group_reporting -name=file1 -- sequencial write fio -filename=/mnt/efs/fio_test -direct=1 -rw=write -bs=4k -size=2G -numjobs=64 -runtime=10 -group_reporting -name=file1 -- ramdom write fio -filename=/mnt/efs/fio_test -direct=1 -rw=randwrite -bs=4k -size=2G -numjobs=64 -runtime=10 -group_reporting -name=file1 結果 #sequencial read read : io=151396KB, bw=15114KB/s, iops=3778, runt= 10017msec #ramdom read read : io=427984KB, bw=42739KB/s, iops=10684, runt= 10014msec #sequencial write write: io=9192.0KB, bw=912516B/s, iops=222, runt= 10315msec #ramdom write write: io=9848.0KB, bw=980300B/s, iops=239, runt= 10287msec block size が 32mの場合 -- sequencial read fio -filename=/mnt/efs/fio_test -direct=1 -rw=read -bs=32m -size=2G -numjobs=16 -runtime=10 -group_reporting -name=file1 -- ramdom read fio -filename=/mnt/efs/fio_test -direct=1 -rw=randread -bs=32m -size=2G -numjobs=16 -runtime=10 -group_reporting -name=file1 -- sequencial write fio -filename=/mnt/efs/fio_test -direct=1 -rw=write -bs=32m -size=2G -numjobs=16 -runtime=10 -group_reporting -name=file1 -- ramdom write fio -filename=/mnt/efs/fio_test -direct=1 -rw=randwrite -bs=32m -size=2G -numjobs=16 -runtime=10 -group_reporting -name=file1 結果 #sequencial read read : io=1536.0MB, bw=109990KB/s, iops=3, runt= 14300msec #ramdom read read : io=1504.0MB, bw=110196KB/s, iops=3, runt= 13976msec #sequencial write write: io=1504.0MB, bw=108404KB/s, iops=3, runt= 14207msec #ramdom write write: io=1472.0MB, bw=109808KB/s, iops=3, runt= 13727msec その他 [ec2-user@bastin ~]$ nslookup fs-xxxxxx.efs.ap-northeast-1.amazonaws.com Server: 10.0.0.2 Address: 10.0.0.2#53 Non-authoritative answer: Name: fs-xxxxxxx.efs.ap-northeast-1.amazonaws.com Address: 10.0.2.177 [ec2-user@bastin ~]$ --- ### Aurora(PostgreSQL)のbytea列にバイナリデータをpythonでインサートする date: 2020-06-05 url: https://zatoima.github.io/aws-aurora-bytea-insert-binary-data.html tags: AWS, Aurora, PostgreSQL, Python はじめに バイナリデータの操作をpsqlから実施しようとする機会はあまりないと思うが、Aurora/RDSでは pg_read_binary_fileファンクションがpermission denied for function pg_read_binary_fileが使用できない。理由としてpg_read_binary_fileファンクションの所有者がrdsadminというログイン不可なユーザとなっているため使用することが出来ない。また、pg_read_binary_fileはサーバサイドのファンクションなので、psqlでログインしている状態でEC2上(Bastin)のファイルをbytea列にINSERTということは不可となる。 postgres> create table test01(id serial primary key,data bytea); CREATE TABLE postgres> insert into test01 (data) values (pg_read_binary_file('/home/ec2-user/test.pdf')); permission denied for function pg_read_binary_file postgres> SELECT proacl FROM pg_proc WHERE proname='pg_read_binary_file'; +-----------------------+ | proacl | |-----------------------| | {rdsadmin=X/rdsadmin} | | {rdsadmin=X/rdsadmin} | | {rdsadmin=X/rdsadmin} | +-----------------------+ Pythonのpsycopg2を使ってAurora PostgreSQLにデータをインサートするサンプルスクリプト aws-overview.pdfというファイルをDBに格納することとします。 python実行と同じディレクトリにtest.pdfを配置して実行 import psycopg2 import psycopg2.extras conn = psycopg2.connect("host=aurorapgsqlv1.cluster-xxxxxx.ap-northeast-1.rds.amazonaws.com port=5432 dbname=postgres user=postgres password=postgres") cur = conn.cursor() img = open('aws-overview.pdf', 'rb').read() cur.execute("create table ins_bytea(id serial,pdfdata bytea)") cur.execute("INSERT INTO ins_bytea (pdfdata) values (%s)", (psycopg2.Binary(img),)) conn.commit() cur.close() conn.close() 結果 格納されたバイナリデータを取り出す方法 aws-overview_export.pdfというファイル名で抽出。 import psycopg2 import psycopg2.extras conn = psycopg2.connect("host=aurorapgsqlv1.cluster-xxxxxx.ap-northeast-1.rds.amazonaws.com port=5432 dbname=postgres user=postgres password=postgres") cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor) cur.execute("SELECT pdfdata FROM ins_bytea;") row = cur.fetchone() pic = row['pdfdata'] f = open('aws-overview_export.pdf', 'wb') f.write(pic) f.close() cur.close() conn.close() 特に差分も無し。 [ec2-user@bastin ~]$ diff aws-overview.pdf aws-overview_export.pdf [ec2-user@bastin ~]$ 参考 PythonからPostgreSQLに接続する方法 | アシスト https://www.ashisuto.co.jp/db_blog/article/20160308_postgresql_with_python.html --- ### OracleとPostgreSQLのトランザクション差異について整理する date: 2020-06-02 url: https://zatoima.github.io/oracle-postgresql-transaction-different.html tags: Oracle, PostgreSQL, DB Migration OracleとPostgreSQLのトランザクション分離レベルは同じREAD COMMITTEDだが、トランザクションによってはそれぞれのデータベースで動作が異なる場合がある。関数の違いや機能差異というのは試験でエラーになるが、この仕様差異はエラーにならず、データの結果差異に繋がることから非常に厄介な問題である。 トランザクション分離レベルの概要等は以前にこちらの記事で書いた。 トランザクション分離レベル(ISOLATION LEVEL)と各DBエンジンについて | my opinion is my own https://zatoima.github.io/oracle-mysql-postgresql-isolation-level.html 今回は上記で触れられなかった各DBエンジンの挙動の違いについてメモしておく。このトランザクション差異の話は有名だと思っているが、あまりネット上で「何故そうなるか?」の観点で記載された記事が無かったので、調査した内容と実機検証の結果を書き留める。(もし誤りがあればご指摘ください。) トランザクションの結果が異なるケースについて Writeの競合 - oracle PostgreSQL 時系列 tx1 tx2 tx1 tx2 1 select * from t1; select * from t1; select * from t1; select * from t1; 2 begin; 3 update t1 set b = b + 1; update t1 set b = b + 1; 4 begin; 5 delete from t1 where b = 3; delete from t1 where b = 3; 6 commit; commit; 7 commit; commit; 8 select * from t1; select * from t1; select * from t1; select * from t1; 実際に上記の手順を実行した場合は下記の結果となる。赤枠で囲っている箇所のトランザクションの動作が異なる。(※markdownで上手く表に出来なかったため画像にしました。) Oracleの動作仕様 Oracleの場合は、下記マニュアルにこの動作仕様の説明が記載されている。 データの同時実行性と整合性 https://docs.oracle.com/cd/E57425_01/121/CNCPT/consist.htm コミット読取りトランザクション内での書込みの競合 コミット読取りトランザクションでは、未コミットの同時実行トランザクション(ブロックしているトランザクションとも呼ばれる)によって更新された行の変更を試行すると、書込みの競合が発生します。コミット読取りトランザクションは、ブロックしているトランザクションが終了して行ロックが解除されるまで待機します。 ブロックしているトランザクションがコミットされてロックが解除された場合、待機しているトランザクションでは、新たに変更された行に対して更新が実行されます。 上記に記載されている通り、ブロックしているトランザクションがコミットされてロックが解除された場合、待機しているトランザクションでは、新たに変更された行に対して更新が実行されます。とあるので、No.6のtx1のCommit実行時にNo.5のdelete from t1 where b = 3;はNo.3の計算結果を踏まえて削除処理が実行される。 PostgreSQLの動作仕様 PostgreSQLの場合は、下記がマニュアルの該当箇所となる。 13.2. トランザクションの分離 https://www.postgresql.jp/document/11/html/transaction-iso.html UPDATE、DELETE、SELECT FOR UPDATE、およびSELECT FOR SHAREコマンドは対象行を検索する際にSELECTコマンドと同じように振舞います。 これらのコマンドは、問い合わせが開始された時点で既にコミットされた対象行のみを検出します。 しかし、その対象行は、検出されるまでに、同時実行中の他のトランザクションによって、既に更新(もしくは削除あるいはロック)されてしまっているかもしれません。 このような場合更新されるべき処理は、最初の更新トランザクションが(それがまだ進行中の場合)コミットもしくはロールバックするのを待ちます。 最初の更新処理がロールバックされるとその結果は無視されて、2番目の更新処理で元々検出した行の更新を続行することができます。 最初の更新処理がコミットされると、2番目の更新処理では、最初の更新処理により行が削除された場合はその行を無視します。 行が削除されなかった時の更新処理は、最初のコミットで更新された行に適用されます。 コマンドの検索条件(WHERE句)は、更新された行がまだその検索条件に一致するかどうかの確認のため再評価されます。 検索条件と一致している場合、2番目の更新処理は、更新された行を使用して処理を開始します。 最初の更新処理がコミットされると、2番目の更新処理では、最初の更新処理により行が削除された場合はその行を無視します。 行が削除されなかった時の更新処理は、最初のコミットで更新された行に適用されます。とあるので、No.6のtx1のCommit実行時に最初の更新処理により行が削除されたので、その行の処理についてはskipする。 上記の通り、OracleではSQL文が再評価(=再起動)されて実行されるのに対して、PostgreSQLでは行が削除された場合は、該当行を無視するので結果の差異が生じる。(個人的にPostgreSQLのこの挙動は分かりづらく感じる。) 次に青枠で囲っているcommitをrollbackしてみる。(最初の更新処理がロールバックされるとその結果は無視されて、2番目の更新処理で元々検出した行の更新を続行することができます。という文章の確認) この場合は、元々のb=3のデータが削除される。Oracleにおいても下記記載がある通り、同様の挙動となる。当然結果も同じとなる。 データの同時実行性と整合性 https://docs.oracle.com/cd/E57425_01/121/CNCPT/consist.htm ブロックしているトランザクションがロールバックされた場合、待機しているトランザクションでは、ブロックしているトランザクションが存在していなかったかのように、ロックされていた行が変更されます。 select for updateとdeleteの競合 次にこのパターンを確認する。 oracle PostgreSQL 時系列 tx1 tx2 tx1 tx2 1 SELECT * FROM t1 ORDER BY a; SELECT * FROM t1 ORDER BY a; 2 BEGIN; 3 SELECT a, b FROM t1 WHERE a = (SELECT MIN(a) FROM t1) FOR UPDATE; SELECT a, b FROM t1 WHERE a = (SELECT MIN(a) FROM t1) FOR UPDATE; 4 BEGIN; 5 SELECT a, b FROM t1 WHERE a = (SELECT MIN(a) FROM t1) FOR UPDATE; SELECT a, b FROM t1 WHERE a = (SELECT MIN(a) FROM t1) FOR UPDATE; 6 DELETE FROM t1 WHERE a = 1; DELETE FROM t1 WHERE a = 1; 7 COMMIT; COMMIT; 上記のトランザクション実行時の結果は次の通り。 Oracleの動作仕様 基本的な考え方はwriteの競合パターンの考え方と同一で良いと考えるが、下記マニュアルにある通り、選択した行が更新または削除された場合は再度問い合わせ文を再起動して評価をし直す。したがって、この場合はNo.7のcommitのタイミングで再評価され、その時点の最小データである2がクエリされることになる。 アプリケーション開発者用のSQL処理 https://docs.oracle.com/cd/E57425_01/121/ADFNS/adfns_sqlproc.htm#i1025003 問合せの実行中に、SELECT FOR UPDATEに対する結果セットが変化する場合があります。たとえば、問合せ開始後に問合せで選択された列が更新されたり、行が削除された場合です。このような場合、SELECT FOR UPDATEは変更されなかった行でロックを取得し、このロックを使用して表の読取り一貫性スナップショットを取得してから、残りのロックを取得するために問合せを再起動します。 PostgreSQLの動作仕様 writeの競合パターンと同様に「最初の更新処理がコミットされると、2番目の更新処理では、最初の更新処理により行が削除された場合はその行を無視します。 」となるので0件となる。 参考 SQL移行調査編 https://pgecons-sec-tech.github.io/tech-report/pdf/09_SqlMigrationResearch.pdf Oracle DBとPostgreSQLで異なる処理結果、「仕様差」問題に要注意 | 日経クロステック(xTECH) https://xtech.nikkei.com/atcl/nxt/column/18/00817/061300007/ 13.2. トランザクションの分離 https://www.postgresql.jp/document/11/html/transaction-iso.html Oracle/MySQL/PostgreSQLにおけるサブクエリを含むDMLの非互換性 - SH2の日記 https://sh2.hatenablog.jp/entry/20131223 ept/hermitage: What are the differences between the transaction isolation levels in databases? This is a suite of test cases which differentiate isolation levels. https://github.com/ept/hermitage --- ### AWS Schema Conversion Toolを使用したOracleからAurora(PostgreSQL)への変換結果 date: 2020-05-29 url: https://zatoima.github.io/aws-sct-oracle-to-aurora-postgresql-conversion.html tags: AWS, SCT, Oracle, PostgreSQL, DB Migration AWS Schema Conversion Toolでどのように変換されるかの確認。DDL定義についてはAWSのDatabase Migration Playbookから拝借致しました。なお、対象はAurora(PostgreSQL)で実施しましたが、RDS(PostgreSQL)でも結果は変わりませんでした。 Oracle CREATE文 CREATE TABLE "DATATYPES"( "BFILE" BFILE, "BINARY_FLOAT" BINARY_FLOAT, "BINARY_DOUBLE" BINARY_DOUBLE, "BLOB" BLOB, "CHAR" CHAR(10 BYTE), "CHARACTER" CHAR(10 BYTE), "CLOB" CLOB, "NCLOB" NCLOB, "DATE" DATE, "DECIMAL" NUMBER(3,2), "DEC" NUMBER(3,2), "DOUBLE_PRECISION" FLOAT(126), "FLOAT" FLOAT(3), "INTEGER" NUMBER(*,0), "INT" NUMBER(*,0), "INTERVAL_YEAR" INTERVAL YEAR(4) TO MONTH, "INTERVAL_DAY" INTERVAL DAY(4) TO SECOND(4), "LONG" LONG, "NCHAR" NCHAR(10), "NCHAR_VARYING" NVARCHAR2(10), "NUMBER" NUMBER(9,9), "NUMBER1" NUMBER(9,0), "NUMBER(*)" NUMBER, "NUMERIC" NUMBER(9,9), "NVARCHAR2" NVARCHAR2(10), "RAW" RAW(10), "REAL" FLOAT(63), "ROW_ID" ROWID, "SMALLINT" NUMBER(*,0), "TIMESTAMP" TIMESTAMP(5), "TIMESTAMP WITH TIME ZONE" TIMESTAMP(5) WITH TIME ZONE, "UROWID" UROWID(10), "VARCHAR" VARCHAR2(10 BYTE), "VARCHAR2" VARCHAR2(10 BYTE), "XMLTYPE" "PUBLIC"."XMLTYPE" ); テーブル定義 SQL> desc DATATYPES; Name Null? Type ----------------------------------------- -------- ---------------------------- BFILE BINARY FILE LOB BINARY_FLOAT BINARY_FLOAT BINARY_DOUBLE BINARY_DOUBLE BLOB BLOB CHAR CHAR(10) CHARACTER CHAR(10) CLOB CLOB NCLOB NCLOB DATE DATE DECIMAL NUMBER(3,2) DEC NUMBER(3,2) DOUBLE_PRECISION FLOAT(126) FLOAT FLOAT(3) INTEGER NUMBER(38) INT NUMBER(38) INTERVAL_YEAR INTERVAL YEAR(4) TO MONTH INTERVAL_DAY INTERVAL DAY(4) TO SECOND(4) LONG LONG NCHAR NCHAR(10) NCHAR_VARYING NVARCHAR2(10) NUMBER NUMBER(9,9) NUMBER1 NUMBER(9) NUMBER(* ) NUMBER NUMERIC NUMBER(9,9) NVARCHAR2 NVARCHAR2(10) RAW RAW(10) REAL FLOAT(63) ROW_ID ROWID SMALLINT NUMBER(38) TIMESTAMP TIMESTAMP(5) TIMESTAMP WITH TIME ZONE TIMESTAMP(5) WITH TIME ZONE UROWID ROWID VARCHAR VARCHAR2(10) VARCHAR2 VARCHAR2(10) XMLTYPE PUBLIC.XMLTYPE STORAGE BINARY PostgreSQL CREATE文 CREATE TABLE IF NOT EXISTS datatypes( bfile CHARACTER VARYING(255), binary_float REAL, binary_double DOUBLE PRECISION, blob BYTEA, char CHARACTER(10), character CHARACTER(10), clob TEXT, nclob TEXT, date TIMESTAMP(0) WITHOUT TIME ZONE, decimal NUMERIC(3,2), dec NUMERIC(3,2), double_precision DOUBLE PRECISION, float DOUBLE PRECISION, integer NUMERIC(38,0), int NUMERIC(38,0), interval_year INTERVAL YEAR TO MONTH, interval_day INTERVAL DAY TO SECOND(4), long TEXT, nchar CHARACTER(10), nchar_varying CHARACTER VARYING(10), number NUMERIC(9,9), number1 NUMERIC(9,0), "NUMBER(*)" DOUBLE PRECISION, numeric NUMERIC(9,9), nvarchar2 CHARACTER VARYING(10), raw BYTEA, real DOUBLE PRECISION, row_id CHARACTER(255), smallint NUMERIC(38,0), timestamp TIMESTAMP(5) WITHOUT TIME ZONE, "TIMESTAMP WITH TIME ZONE" TIMESTAMP(5) WITH TIME ZONE, urowid CHARACTER VARYING, varchar CHARACTER VARYING(10), varchar2 CHARACTER VARYING(10), xmltype XML ); テーブル定義 postgres> \d datatypes; +--------------------------+--------------------------------+-------------+ | Column | Type | Modifiers | |--------------------------+--------------------------------+-------------| | bfile | character varying(255) | | | binary_float | real | | | binary_double | double precision | | | blob | bytea | | | char | character(10) | | | character | character(10) | | | clob | text | | | nclob | text | | | date | timestamp(0) without time zone | | | decimal | numeric(3,2) | | | dec | numeric(3,2) | | | double_precision | double precision | | | float | double precision | | | integer | numeric(38,0) | | | int | numeric(38,0) | | | interval_year | interval year to month | | | interval_day | interval day to second(4) | | | long | text | | | nchar | character(10) | | | nchar_varying | character varying(10) | | | number | numeric(9,9) | | | number1 | numeric(9,0) | | | NUMBER(*) | double precision | | | numeric | numeric(9,9) | | | nvarchar2 | character varying(10) | | | raw | bytea | | | real | double precision | | | row_id | character(255) | | | smallint | numeric(38,0) | | | timestamp | timestamp(5) without time zone | | | TIMESTAMP WITH TIME ZONE | timestamp(5) with time zone | | | urowid | character varying | | | varchar | character varying(10) | | | varchar2 | character varying(10) | | | xmltype | xml | | +--------------------------+--------------------------------+-------------+ OracleとPostgreSQLを対比した結果は次の通りです。 OracleとPostgreSQLの対比一覧 No. Oracle (※descの結果) PostgreSQL (\d メタコマンド結果) 1 BINARY FILE LOB character varying(255) 2 BINARY_FLOAT real 3 BINARY_DOUBLE double precision 4 BLOB bytea 5 CHAR(10) character(10) 6 CHAR(10) character(10) 7 CLOB text 8 NCLOB text 9 DATE timestamp(0) without time zone 10 NUMBER(3,2) numeric(3,2) 11 NUMBER(3,2) numeric(3,2) 12 FLOAT(126) double precision 13 FLOAT(3) double precision 14 NUMBER(38) numeric(38,0) 15 NUMBER(38) numeric(38,0) 16 INTERVAL YEAR(4) TO MONTH interval year to month 17 INTERVAL DAY(4) TO SECOND(4) interval day to second(4) 18 LONG text 19 NCHAR(10) character(10) 20 NVARCHAR2(10) character varying(10) 21 NUMBER(9,9) numeric(9,9) 22 NUMBER(9) numeric(9,0) 23 NUMBER double precision 24 NUMBER(9,9) numeric(9,9) 25 NVARCHAR2(10) character varying(10) 26 RAW(10) bytea 27 FLOAT(63) double precision 28 ROWID character(255) 29 NUMBER(38) numeric(38,0) 30 TIMESTAMP(5) timestamp(5) without time zone 31 TIMESTAMP(5) WITH TIME ZONE timestamp(5) with time zone 32 ROWID character varying 33 VARCHAR2(10) character varying(10) 34 VARCHAR2(10) character varying(10) 35 PUBLIC.XMLTYPE STORAGE BINARY xml --- ### S3からRDS/Aurora(PostgreSQL)にCSVファイルをインポートする date: 2020-05-25 url: https://zatoima.github.io/aws-aurora-rds-s3-import.html tags: AWS, Aurora, RDS, PostgreSQL 事前設定のIAMロールの設定から実際のRDS(PostgreSQL)に対してCSVファイルのロードを行う。RDSとAuroraで手順に関しては大きく差異はないが、Amazon S3 から Aurora PostgreSQL にインポートするには、データベースで PostgreSQL バージョン 10.7 以降を実行している必要がある。 詳細の手順や制限事項等は下記マニュアルを参照。 PostgreSQL 互換で Amazon Aurora にデータを移行する - Amazon Aurora https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Migrating.html#USER_PostgreSQL.S3Import IAMロールの設定 データロードのための下準備としてIAMロールの設定を行う。 IAMの画面から「ロールの作成」を選択 S3を選択 「AmazonS3ReadOnlyAccess」を選択してポリシーをアタッチする。 必要に応じてタグを設定。 ロール名は「importfroms3」とした。 作成したロールの画面に移動する。 「信頼関係」-「信頼関係の編集」へと移動して下記を上書きして貼り付ける。 { "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": [ "rds.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] } 「Amazon Aurora クラスターに IAM ロール」を追加する Aurora クラスタに移動して「IAMロールの管理」を選択。 IAMロールの管理のところにて先程作成した「importfroms3」ロールを追加する。機能は「s3import」を指定。 ここまでで事前設定が終わりとなる。 実際のインポート自体はCLI上でコマンドで実施するが、まずはaws_s3を有効化する。 CREATE EXTENSION aws_s3 CASCADE; インポートコマンド SELECT aws_s3.table_import_from_s3( 'aozora_kaiseki', '', '(format csv)', 'nep-s3-bk', 'utf8_all.csv', 'ap-northeast-1' ); 関数の引数は下記の通り。 PostgreSQL 互換で Amazon Aurora にデータを移行する - Amazon Aurora https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Migrating.html#USER_PostgreSQL.S3Import.FileFormats aws_s3.table_import_from_s3 関数を使用して Amazon S3 データをインポートする dbname=> SELECT aws_s3.table_import_from_s3( 'テーブル名', 'カラムリスト', -- 空文字('')の場合は、テーブルのカラムと一致 'PostgreSQL COPYの引数・フォーマット', 'S3バケット名', 'S3キー', 'S3リージョン' ); 約10GB相当のデータを約4分でインポートすることが出来た。 postgres@rdspgsqlv1:postgres> SELECT aws_s3.table_import_from_s3( 'aozora_kaiseki', '', '(format csv)', 'nep-s3-bk', 'utf8_all.csv', 'ap-northeast-1' ); +--------------------------------------------------------------------------------------------------+ | table_import_from_s3 | |--------------------------------------------------------------------------------------------------| | 87701673 rows imported into relation "aozora_kaiseki" from file utf8_all.csv of 6539180310 bytes | +--------------------------------------------------------------------------------------------------+ SELECT 1 Time: 272.534s (4 minutes), executed in: 272.522s (4 minutes) postgres@rdspgsqlv1:postgres> psqlのコピーコマンドを使ったCSVインポートと比較してみたが、特に時間としては変わらなかった。 ■CSVインポート(COPYコマンド) [ec2-user@bastin ~]$ time psql -h rdspgsqlv1.xxxxxxxx.ap-northeast-1.rds.amazonaws.com -d postgres -U postgres -c "COPY aozora_kaiseki(file,num,row,word,subtype1,subtype2,subtype3,subtype4,conjtype,conjugation,basic,ruby,pronunce) from stdin with csv DELIMITER ','" < /home/ec2-user/utf8_all.csv COPY 87701673 real 4m20.753s user 0m19.471s sys 0m6.427s --- ### 指定したRDS/AuroraのログをCLIで一括ダウンロードする date: 2020-05-23 url: https://zatoima.github.io/aws-aurora-rds-log-download.html tags: PostgreSQL, AWS, Aurora, RDS シェルスクリプト #!/bin/bash DB_INSTANCE=$1 logfilelist=$(aws rds describe-db-log-files --db-instance-identifier $DB_INSTANCE --no-paginate --output text | cut -f3 | cut -d '/' -f2 | sort) for logfile in $logfilelist; do echo "`date +%Y-%m-%d-%H-%M-%S`: "Downloading log file = $logfile"" aws rds download-db-log-file-portion --db-instance-identifier $DB_INSTANCE --output text --starting-token 0 --log-file-name error/$logfile > $logfile done 実行 [ec2-user@bastin]$ vi rdslog_get.sh [ec2-user@bastin]$ ./rdslog_get.sh aurorapgsqlv1 2020-05-14-03-35-05: Downloading log file = pg_upgrade_dump_13322.log.1589425177488 2020-05-14-03-35-06: Downloading log file = pg_upgrade_dump_16384.log.1589425177488 2020-05-14-03-35-06: Downloading log file = pg_upgrade_dump_16399.log.1589425177488 2020-05-14-03-35-07: Downloading log file = pg_upgrade_dump_1.log.1589425177488 2020-05-14-03-35-07: Downloading log file = pg_upgrade_internal.log.1589425177488 2020-05-14-03-35-08: Downloading log file = pg_upgrade_server.log.1589425177488 2020-05-14-03-35-08: Downloading log file = postgres.log 2020-05-14-03-35-09: Downloading log file = postgresql.log.2020-05-14-02 2020-05-14-03-35-09: Downloading log file = postgresql.log.2020-05-14-0259 2020-05-14-03-35-10: Downloading log file = postgresql.log.2020-05-14-0300 --- ### EC2で使用できるRHELのAMI一覧 date: 2020-05-22 url: https://zatoima.github.io/aws-ec2-available-rhel-ami-version.html tags: AWS, EC2 こちらを参考にRHEL 7とRHEL 8のAMIの調査方法をメモ 【小ネタ】Red Hat Enterprise LinuxのAMIの調べ方 – サーバーワークスエンジニアブログ http://blog.serverworks.co.jp/tech/2019/06/18/post-71160/ RHEL 7 [ec2-user@bastin ~]$ aws ec2 describe-images --owners 309956199498 --query 'Images[*].[CreationDate,Name,ImageId]' --filters "Name=name,Values=RHEL-7.?*GA*x86*" --region ap-northeast-1 --output table | sort -r | DescribeImages | | 2020-02-26T17:20:13.000Z | RHEL-7.8_HVM_GA-20200225-x86_64-1-Hourly2-GP2 | ami-038a794b902fa0afc | | 2019-07-24T09:17:45.000Z | RHEL-7.7_HVM_GA-20190723-x86_64-1-Hourly2-GP2 | ami-0dc41c7805e171046 | | 2019-02-06T00:23:09.000Z | RHEL-7.6_HVM_GA-20190128-x86_64-0-Hourly2-GP2 | ami-00b95502a4d51a07e | | 2018-10-17T14:14:10.000Z | RHEL-7.6_HVM_GA-20181017-x86_64-0-Hourly2-GP2 | ami-08419d23bf91152e4 | | 2018-03-23T21:14:36.000Z | RHEL-7.5_HVM_GA-20180322-x86_64-1-Hourly2-GP2 | ami-6b0d5f0d | | 2017-08-08T15:45:51.000Z | RHEL-7.4_HVM_GA-20170808-x86_64-2-Hourly2-GP2 | ami-30ef0556 | | 2017-07-24T15:55:34.000Z | RHEL-7.4_HVM_GA-20170724-x86_64-1-Hourly2-GP2 | ami-3901e15f | | 2016-10-26T22:33:03.000Z | RHEL-7.3_HVM_GA-20161026-x86_64-1-Hourly2-GP2 | ami-5de0433c | | 2015-11-12T21:11:15.000Z | RHEL-7.2_HVM_GA-20151112-x86_64-1-Hourly2-GP2 | ami-0dd8f963 | | 2015-02-26T16:34:39.000Z | RHEL-7.1_HVM_GA-20150225-x86_64-1-Hourly2-GP2 | ami-b1b458b1 | | 2015-02-16T16:17:50.000Z | RHEL-7.0_HVM_GA-20150209-x86_64-1-Hourly2-GP2 | ami-e532d3e5 | | 2014-10-20T14:13:11.000Z | RHEL-7.0_HVM_GA-20141017-x86_64-1-Hourly2-GP2 | ami-35556534 | | 2014-05-28T20:36:35.000Z | RHEL-7.0_GA_HVM-x86_64-3-Hourly2 | ami-87206d86 | +---------------------------+-------------------------------------------------+------------------------+ +---------------------------+-------------------------------------------------+------------------------+ -------------------------------------------------------------------------------------------------------- RHEL 8 [ec2-user@bastin ~]$ aws ec2 describe-images --owners 309956199498 --query 'Images[*].[CreationDate,Name,ImageId]' --filters "Name=name,Values=RHEL-8.?*x86*" --region ap-northeast-1 --output table | sort -r | DescribeImages | | 2020-04-23T15:39:00.000Z | RHEL-8.2.0_HVM-20200423-x86_64-0-Hourly2-GP2 | ami-07dd14faa8a17fb3e | | 2020-01-14T22:28:26.000Z | RHEL-8.2.0_HVM_BETA-20191219-x86_64-0-Hourly2-GP2 | ami-0f3a7097e011d9532 | | 2019-10-30T10:14:36.000Z | RHEL-8.1.0_HVM-20191029-x86_64-0-Hourly2-GP2 | ami-0302fadfb901ae198 | | 2019-09-23T20:01:56.000Z | RHEL-8.0_HVM-20190920-x86_64-0-Hourly2-GP2 | ami-0c45b9b8b241f629f | | 2019-07-21T19:37:12.000Z | RHEL-8.1.0_HVM_BETA-20190701-x86_64-0-Hourly2-GP2 | ami-0c09ca180274c253a | | 2019-06-19T19:55:31.000Z | RHEL-8.0.0_HVM-20190618-x86_64-1-Hourly2-GP2 | ami-09f31cc5d5eecca1a | | 2019-05-20T22:19:27.000Z | RHEL-8.0.0_HVM-20190520-x86_64-1-Hourly2-GP2 | ami-0c3b878cc19d12d6c | | 2019-04-26T20:05:27.000Z | RHEL-8.0.0_HVM-20190426-x86_64-1-Hourly2-GP2 | ami-03c6a4362c5fb8c61 | | 2018-11-13T21:36:49.000Z | RHEL-8.0_HVM_BETA-20181113-x86_64-1-Hourly2-GP2 | ami-0d938ac9c11076133 | +---------------------------+-----------------------------------------------------+------------------------+ +---------------------------+-----------------------------------------------------+------------------------+ ------------------------------------------------------------------------------------------------------------ --- ### PostgreSQLのメジャーバージョンアップ拡張機能のpg_upgradeを使用する date: 2020-05-20 url: https://zatoima.github.io/postgresql-versionup-pg_upgrade-extention.html tags: PostgreSQL pg_upgradeの概要 pg_upgrade https://www.postgresql.jp/document/12/html/pgupgrade.html pg_upgradeはPostgreSQLのメジャーバージョンアップ時に使用されるツールで、バックアップ・リストアやpg_dump等の論理的な移行をせずに旧バージョンの PostgreSQLのデータを新バージョンのPostgreSQLに移行することが可能。 アウトオブプレース・アップグレードとインプレース・アップグレードの考えであり、pg_upgradeはインプレース・アップグレードとなる。一方の論理的な移行(レプリケーション、pg_dump移行等)はアウトオブプレース・アップグレードとなる。ダウンタイムは必要だが、一般的なバックアップリストア方式よりも時間は短くなる傾向にある。 pg_upgradeには2つのモードがある。 モード 説明 コピーモード 既存のデータベースクラスタのデータを、新規PostgreSQL のデータベースクラスタにコピー(デフォルト) リンクモード 既存のデータベースクラスタと新規データベースクラスタをハードリンクで繋ぎ、データを共有する ※コピーモードの注意点として下記がある pg_upgrade直後は一時的にデータ容量が2倍になる。(./delete_old_cluster.shで削除すれば問題無し) (未検証だが、おそらく)移行時間がデータ容量と比例する ※リンクモードの注意点として下記がある ファイルのコピーがないのでアップグレード自体は非常に高速となる 必要なディスクもコピーモードに比べて少ない 新しいPostgreSQLクラスタを一度実行すると旧クラスタは使用できなくなる 新旧のクラスタが同じファイルシステム上にあることが必要 手順 事前準備 この環境自体は下記記事で作った一時的な検証環境を使用。 EC2上のRHEL8(Red Hat Enterprise Linux)にPostgreSQL11と12をyumでインストール | my opinion is my own https://zatoima.github.io/aws-ec2-rhel-postgresql-install.html 検証なのでゼロベースからスタートする。 PostgreSQLの停止 . $HOME/.pgsql11_env pg_ctl stop . $HOME/.pgsql12_env pg_ctl stop データファイルの削除 rm -rf $HOME/11/* rm -rf $HOME/12/* 初期化(rootで実行) /usr/pgsql-11/bin/postgresql-11-setup initdb /usr/pgsql-12/bin/postgresql-12-setup initdb テストデータのロード . $HOME/.pgsql11_env pg_ctl start pgcli CREATE TABLE aozora_kaisekidata(file VARCHAR(30),num INT,row INT,word TEXT,subtype1 VARCHAR(30),subtype2 VARCHAR(30),subtype3 VARCHAR(30),subtype4 VARCHAR(10),conjtype VARCHAR(15),conjugation VARCHAR(15),basic TEXT,ruby TEXT,pronunce TEXT ); time psql -d postgres -U postgres -c "COPY aozora_kaisekidata(file,num,row,word,subtype1,subtype2,subtype3,subtype4,conjtype,conjugation,basic,ruby,pronunce) from stdin with csv DELIMITER ','" < $HOME/utf8_all.csv ここでoid2nameでオブジェクトの情報を控えておく。 [postgres@pgsql ~]$ oid2name -t aozora_kaisekidata From database "postgres": Filenode Table Name ------------------------------ 16384 aozora_kaisekidata また、この状態での容量は約10GBとなる。 postgres> SELECT datname, pg_size_pretty(pg_database_size(datname)) FROM pg_database; +-----------+------------------+ | datname | pg_size_pretty | |-----------+------------------| | postgres | 9584 MB | | template1 | 7585 kB | | template0 | 7585 kB | +-----------+------------------+ ちなみに、このデータ自体は下記方法で作成している。 青空文庫作品の形態素解析データをRDS PostgreSQLにインポートする | my opinion is my own https://zatoima.github.io/postgresql-aozora-bunko-data-import.html 事前準備(PostgreSQLの停止) . $HOME/.pgsql11_env pg_ctl stop . $HOME/.pgsql12_env pg_ctl stop pg_upgradeの実施 1.) コピーモードでpg_upgradeを実施 10GB弱のDB容量のアップグレード実行に約3分程度掛かっている。 [postgres@pgsql ~]$ . $HOME/.pgsql12_env [postgres@pgsql ~]$ time /usr/pgsql-12/bin/pg_upgrade -r -d /var/lib/pgsql/11/data -D /var/lib/pgsql/12/data -b /usr/pgsql-11/bin -B /usr/pgsql-12/bin Performing Consistency Checks ----------------------------- Checking cluster versions ok Checking database user is the install user ok Checking database connection settings ok Checking for prepared transactions ok Checking for reg* data types in user tables ok Checking for contrib/isn with bigint-passing mismatch ok Checking for tables WITH OIDS ok Checking for invalid "sql_identifier" user columns ok Creating dump of global objects ok Creating dump of database schemas ok Checking for presence of required libraries ok Checking database user is the install user ok Checking for prepared transactions ok If pg_upgrade fails after this point, you must re-initdb the new cluster before continuing. Performing Upgrade ------------------ Analyzing all rows in the new cluster ok Freezing all rows in the new cluster ok Deleting files from new pg_xact ok Copying old pg_xact to new server ok Setting next transaction ID and epoch for new cluster ok Deleting files from new pg_multixact/offsets ok Copying old pg_multixact/offsets to new server ok Deleting files from new pg_multixact/members ok Copying old pg_multixact/members to new server ok Setting next multixact ID and offset for new cluster ok Resetting WAL archives ok Setting frozenxid and minmxid counters in new cluster ok Restoring global objects in the new cluster ok Restoring database schemas in the new cluster ok Copying user relation files ok Setting next OID for new cluster ok Sync data directory to disk ok Creating script to analyze new cluster ok Creating script to delete old cluster ok Upgrade Complete ---------------- Optimizer statistics are not transferred by pg_upgrade so, once you start the new server, consider running: ./analyze_new_cluster.sh Running this script will delete the old cluster's data files: ./delete_old_cluster.sh real 2m45.122s user 0m0.174s sys 0m6.919s [postgres@pgsql ~]$ コピーモードなのでinodeも別となっている。(※リンクモードの場合はここが同一となる。(後述)) [postgres@pgsql ~]$ find . | grep 16384 | xargs ls -li 239076379 -rw-------. 1 postgres postgres 1073741824 May 16 22:54 ./11/data/base/13141/16384 239076383 -rw-------. 1 postgres postgres 1073741824 May 16 22:54 ./11/data/base/13141/16384.1 239076384 -rw-------. 1 postgres postgres 1073741824 May 16 22:55 ./11/data/base/13141/16384.2 239076385 -rw-------. 1 postgres postgres 1073741824 May 16 22:49 ./11/data/base/13141/16384.3 239076386 -rw-------. 1 postgres postgres 1073741824 May 16 22:50 ./11/data/base/13141/16384.4 239076387 -rw-------. 1 postgres postgres 1073741824 May 16 22:50 ./11/data/base/13141/16384.5 239076388 -rw-------. 1 postgres postgres 1073741824 May 16 22:51 ./11/data/base/13141/16384.6 239076389 -rw-------. 1 postgres postgres 1073741824 May 16 22:51 ./11/data/base/13141/16384.7 239076390 -rw-------. 1 postgres postgres 1073741824 May 16 22:52 ./11/data/base/13141/16384.8 239076391 -rw-------. 1 postgres postgres 375709696 May 16 22:53 ./11/data/base/13141/16384.9 239076382 -rw-------. 1 postgres postgres 2490368 May 16 22:53 ./11/data/base/13141/16384_fsm 96472658 -rw-------. 1 postgres postgres 1073741824 May 16 22:55 ./12/data/base/16401/16384 96472661 -rw-------. 1 postgres postgres 1073741824 May 16 22:55 ./12/data/base/16401/16384.1 96472662 -rw-------. 1 postgres postgres 1073741824 May 16 22:56 ./12/data/base/16401/16384.2 96472663 -rw-------. 1 postgres postgres 1073741824 May 16 22:56 ./12/data/base/16401/16384.3 96472664 -rw-------. 1 postgres postgres 1073741824 May 16 22:56 ./12/data/base/16401/16384.4 96472665 -rw-------. 1 postgres postgres 1073741824 May 16 22:56 ./12/data/base/16401/16384.5 96472666 -rw-------. 1 postgres postgres 1073741824 May 16 22:57 ./12/data/base/16401/16384.6 96472667 -rw-------. 1 postgres postgres 1073741824 May 16 22:57 ./12/data/base/16401/16384.7 96472668 -rw-------. 1 postgres postgres 1073741824 May 16 22:57 ./12/data/base/16401/16384.8 96472669 -rw-------. 1 postgres postgres 375709696 May 16 22:57 ./12/data/base/16401/16384.9 96472670 -rw-------. 1 postgres postgres 2490368 May 16 22:57 ./12/data/base/16401/16384_fsm 2.) リンクモードでpg_upgradeを実施 実行自体は10秒も掛からず終わった。 [postgres@pgsql ~]$ time /usr/pgsql-12/bin/pg_upgrade -r -k -d /var/lib/pgsql/11/data -D /var/lib/pgsql/12/data -b /usr/pgsql-11/bin -B /usr/pgsql-12/bin Performing Consistency Checks ----------------------------- Checking cluster versions ok Checking database user is the install user ok Checking database connection settings ok Checking for prepared transactions ok Checking for reg* data types in user tables ok Checking for contrib/isn with bigint-passing mismatch ok Checking for tables WITH OIDS ok Checking for invalid "sql_identifier" user columns ok Creating dump of global objects ok Creating dump of database schemas ok Checking for presence of required libraries ok Checking database user is the install user ok Checking for prepared transactions ok If pg_upgrade fails after this point, you must re-initdb the new cluster before continuing. Performing Upgrade ------------------ Analyzing all rows in the new cluster ok Freezing all rows in the new cluster ok Deleting files from new pg_xact ok Copying old pg_xact to new server ok Setting next transaction ID and epoch for new cluster ok Deleting files from new pg_multixact/offsets ok Copying old pg_multixact/offsets to new server ok Deleting files from new pg_multixact/members ok Copying old pg_multixact/members to new server ok Setting next multixact ID and offset for new cluster ok Resetting WAL archives ok Setting frozenxid and minmxid counters in new cluster ok Restoring global objects in the new cluster ok Restoring database schemas in the new cluster ok Adding ".old" suffix to old global/pg_control ok If you want to start the old cluster, you will need to remove the ".old" suffix from /var/lib/pgsql/11/data/global/pg_control.old. Because "link" mode was used, the old cluster cannot be safely started once the new cluster has been started. Linking user relation files ok Setting next OID for new cluster ok Sync data directory to disk ok Creating script to analyze new cluster ok Creating script to delete old cluster ok Upgrade Complete ---------------- Optimizer statistics are not transferred by pg_upgrade so, once you start the new server, consider running: ./analyze_new_cluster.sh Running this script will delete the old cluster's data files: ./delete_old_cluster.sh real 0m7.014s user 0m0.103s sys 0m0.210s リンクモードなので、例えば./11/data/base/13141/16384.1のファイルのinodeは272636857で同一情報となっている。 [postgres@pgsql ~]$ find . | grep 16384 | xargs ls -li 272636853 -rw-------. 2 postgres postgres 1073741824 May 16 22:42 ./11/data/base/13141/16384 272636857 -rw-------. 2 postgres postgres 1073741824 May 16 22:33 ./11/data/base/13141/16384.1 272636858 -rw-------. 2 postgres postgres 1073741824 May 16 22:33 ./11/data/base/13141/16384.2 272636859 -rw-------. 2 postgres postgres 1073741824 May 16 22:34 ./11/data/base/13141/16384.3 272636860 -rw-------. 2 postgres postgres 1073741824 May 16 22:34 ./11/data/base/13141/16384.4 272636861 -rw-------. 2 postgres postgres 1073741824 May 16 22:35 ./11/data/base/13141/16384.5 272636862 -rw-------. 2 postgres postgres 1073741824 May 16 22:35 ./11/data/base/13141/16384.6 272636863 -rw-------. 2 postgres postgres 1073741824 May 16 22:36 ./11/data/base/13141/16384.7 275458304 -rw-------. 2 postgres postgres 1073741824 May 16 22:36 ./11/data/base/13141/16384.8 275458305 -rw-------. 2 postgres postgres 375709696 May 16 22:38 ./11/data/base/13141/16384.9 272636856 -rw-------. 2 postgres postgres 2490368 May 16 22:38 ./11/data/base/13141/16384_fsm 272636853 -rw-------. 2 postgres postgres 1073741824 May 16 22:42 ./12/data/base/16401/16384 272636857 -rw-------. 2 postgres postgres 1073741824 May 16 22:33 ./12/data/base/16401/16384.1 272636858 -rw-------. 2 postgres postgres 1073741824 May 16 22:33 ./12/data/base/16401/16384.2 272636859 -rw-------. 2 postgres postgres 1073741824 May 16 22:34 ./12/data/base/16401/16384.3 272636860 -rw-------. 2 postgres postgres 1073741824 May 16 22:34 ./12/data/base/16401/16384.4 272636861 -rw-------. 2 postgres postgres 1073741824 May 16 22:35 ./12/data/base/16401/16384.5 272636862 -rw-------. 2 postgres postgres 1073741824 May 16 22:35 ./12/data/base/16401/16384.6 272636863 -rw-------. 2 postgres postgres 1073741824 May 16 22:36 ./12/data/base/16401/16384.7 275458304 -rw-------. 2 postgres postgres 1073741824 May 16 22:36 ./12/data/base/16401/16384.8 275458305 -rw-------. 2 postgres postgres 375709696 May 16 22:38 ./12/data/base/16401/16384.9 272636856 -rw-------. 2 postgres postgres 2490368 May 16 22:38 ./12/data/base/16401/16384_fsm コピーモードとリンクモードの動作の違い コピーモードでは出力ログに「Copying user relation files」セクションがある。 Copying user relation files ok 一方、リンクモードの場合は、下記出力がある。 Adding ".old" suffix to old global/pg_control ok If you want to start the old cluster, you will need to remove the ".old" suffix from /var/lib/pgsql/11/data/global/pg_control.old. Because "link" mode was used, the old cluster cannot be safely started once the new cluster has been started. Linking user relation files 最後に 各種制限がクリアになればpg_upgradeでのメジャーバージョンアップも良いのかな、、、、と。他メジャーバージョン方法も出来れば試してみたい。 --- ### EC2上のRHEL8(Red Hat Enterprise Linux)にPostgreSQL11と12をyumでインストール date: 2020-05-18 url: https://zatoima.github.io/aws-ec2-rhel-postgresql-install.html tags: AWS, EC2, PostgreSQL, RHEL はじめに EC2上のRHEL 8 (Red Hat Enterprise Linux)にPostgreSQL 11と12をyumでインストールしてみる。2つのバージョンを入れるのは後続の記事で整理予定のpg_upgradeの拡張機能を使用した検証をやってみたいから。Amazon Linux2にPostgreSQLをyumでインストールする方法はこちらをどうぞ。 EC2(Amazon Linux2)にPostgreSQLをインストールする | my opinion is my own https://zatoima.github.io/postgresql-ec2-insatll.html Red hatのバージョンはこちら [ec2-user@pgsql ~]$ cat /etc/redhat-release Red Hat Enterprise Linux release 8.2 (Ootpa) リポジトリの追加 sudo yum -y localinstall https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm 参考:PostgreSQL RPM Repository (with Yum) https://yum.postgresql.org/repopackages.php EPELリポジトリの追加 PostgreSQL RPM Repository (with Yum) https://yum.postgresql.org/repopackages.php Please note that PostgreSQL YUM repository depends on EPEL repository for some packages. RHEL/CentOS/, etc. users should install EPEL repo RPM along with PGDG repo RPMs to satisfy dependencies. 上記の記載の通り、EPELリポジトリのいくつかのパッケージに依存しているため、EPELリポジトリを追加する必要がある模様。(特にインストールせずともインストール自体は出来た。) EPEL(Extra Packages for Enterprise Linux)とは、Red Hat Enterprise Linux(RHEL)向けの「追加パッケージ」を提供するリポジトリ。 wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm sudo rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm インストール実施後、epelリポジトリが使用可能になる。 [ec2-user@pgsql ~]$ yum repolist repo id repo name status epel/x86_64 Extra Packages for Enterprise Linux 7 - x86_64 13,273 インストール可能なバージョンの確認 postgresql11と12の最新版の11.8と12.3が使用可能。RHEL7用のリポジトリに入っているPostgreSQLのパッケージ名と微妙に違うような、、、 [ec2-user@pgsql ~]$ sudo yum info postgresql11-server Last metadata expiration check: 1:06:25 ago on Sat 16 May 2020 07:30:17 PM JST. Installed Packages Name : postgresql11-server Version : 11.8 Release : 1PGDG.rhel8 Architecture : x86_64 Size : 19 M Source : postgresql11-11.8-1PGDG.rhel8.src.rpm Repository : @System From repo : pgdg11 Summary : The programs needed to create and run a PostgreSQL server URL : https://www.postgresql.org/ License : PostgreSQL Description : PostgreSQL is an advanced Object-Relational database management system (DBMS). : The postgresql11-server package contains the programs needed to create : and run a PostgreSQL server, which will in turn allow you to create : and maintain PostgreSQL databases. [ec2-user@pgsql ~]$ sudo yum info postgresql12-server Last metadata expiration check: 1:06:37 ago on Sat 16 May 2020 07:30:17 PM JST. Installed Packages Name : postgresql12-server Version : 12.3 Release : 1PGDG.rhel8 Architecture : x86_64 Size : 20 M Source : postgresql12-12.3-1PGDG.rhel8.src.rpm Repository : @System From repo : pgdg12 Summary : The programs needed to create and run a PostgreSQL server URL : https://www.postgresql.org/ License : PostgreSQL Description : PostgreSQL is an advanced Object-Relational database management system (DBMS). : The postgresql12-server package contains the programs needed to create : and run a PostgreSQL server, which will in turn allow you to create : and maintain PostgreSQL databases. PostgreSQL11のインストール PostgreSQL11をインストールしてみる。 sudo yum -y install postgresql11-server バージョンを確認。 [ec2-user@pgsql ~]$ /usr/pgsql-11/bin/postgres --version postgres (PostgreSQL) 11.8 OS側にpostgresユーザが作成される。 [ec2-user@pgsql ~]$ cat /etc/passwd ~中略~ ec2-user:x:1000:1000:Cloud User:/home/ec2-user:/bin/bash postgres:x:26:26:PostgreSQL Server:/var/lib/pgsql:/bin/bash postgresql11-contribとpostgresql11-develも合わせてインストールする。 [ec2-user@pgsql ~]$ sudo yum -y install postgresql11-contrib.x86_64 postgresql11-devel.x86_64 PostgreSQL12のインストール PostgreSQL12をインストールする。(※手順はPostgreSQL11とほぼ一緒) sudo yum -y install postgresql12-server バージョンを確認してみる。 [ec2-user@pgsql ~]$ /usr/pgsql-12/bin/postgres --version postgres (PostgreSQL) 12.3 postgresql11-contribとpostgresql11-develも合わせてインストールする。 [ec2-user@pgsql ~]$ sudo yum -y install postgresql12-contrib.x86_64 postgresql12-devel.x86_64 DB初期化、PostgreSQLの起動停止、接続確認等 DBの初期化を行う。rootで実施。 [root@pgsql ~]# /usr/pgsql-11/bin/postgresql-11-setup initdb Initializing database ... OK [root@pgsql ~]# /usr/pgsql-12/bin/postgresql-12-setup initdb Initializing database ... OK 自動起動設定を行う [root@pgsql ~]# systemctl enable postgresql-11 Created symlink from /etc/systemd/system/multi-user.target.wants/postgresql-11.service to /usr/lib/systemd/system/postgresql-12.service. [root@pgsql ~]# systemctl enable postgresql-12 Created symlink from /etc/systemd/system/multi-user.target.wants/postgresql-12.service to /usr/lib/systemd/system/postgresql-12.service. PostgreSQL11と12で起動ポートが重複するため、PostgreSQL12用のpostgresql.confを修正して一方の起動ポートを変更する sed -i "s/#port = 5432/port = 5433/g" "/var/lib/pgsql/12/data/postgresql.conf" 問題なくPostgreSQLの起動、停止、再起動が出来るか確認する sudo systemctl start postgresql-11.service sudo systemctl stop postgresql-11.service sudo systemctl restart postgresql-11.service sudo systemctl start postgresql-12.service sudo systemctl stop postgresql-12.service sudo systemctl restart postgresql-12.service 環境変数を用意 vi .pgsql11_env -------------- export PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/usr/pgsql-11/bin [ -f /etc/profile ] && source /etc/profile PGDATA=/var/lib/pgsql/11/data export PGDATA export PGPORT=5432 # If you want to customize your settings, # Use the file below. This is not overridden # by the RPMS. [ -f /var/lib/pgsql/.pgsql_profile ] && source /var/lib/pgsql/.pgsql_profile -------------- vi .pgsql12_env -------------- export PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/usr/pgsql-12/bin [ -f /etc/profile ] && source /etc/profile PGDATA=/var/lib/pgsql/12/data export PGDATA export PGPORT=5433 # If you want to customize your settings, # Use the file below. This is not overridden # by the RPMS. [ -f /var/lib/pgsql/.pgsql_profile ] && source /var/lib/pgsql/.pgsql_profile -------------- 接続確認 [postgres@pgsql ~]$ . .pgsql11_env [postgres@pgsql ~]$ [postgres@pgsql ~]$ psql psql (12.3, server 11.8) Type "help" for help. postgres=# select version(); version -------------------------------------------------------------------------------------------- ------------ PostgreSQL 11.8 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.3.1 20191121 (Red Hat 8.3.1 -5), 64-bit (1 row) [postgres@pgsql ~]$ . .pgsql12_env [postgres@pgsql ~]$ psql psql (12.3) Type "help" for help. postgres=# select version(); version -------------------------------------------------------------------------------------------- ------------ PostgreSQL 12.3 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.3.1 20191121 (Red Hat 8.3.1 -5), 64-bit (1 row) 次はこの環境を使ってpg_upgradeの動作確認検証を行う予定。 --- ### 青空文庫作品の形態素解析データをRDS PostgreSQLにインポートする date: 2020-05-17 url: https://zatoima.github.io/postgresql-aozora-bunko-data-import.html tags: PostgreSQL, AWS, Aurora, RDS はじめに 形態素解析データを使用した分析をPostgreSQL上で実施したく、AWS上のRDS(PostgreSQL)へのロード方法をメモ。形態素解析データについてはこちらを使用させて頂きました。 青空文庫形態素解析データ集 http://aozora-word.hahasoha.net/ 対象データ 全データが含まれているこちらのファイルをPostgreSQLにロードすることにしました。 http://aozora-word.hahasoha.net/utf8/utf8_all.csv.gz こちらには青空文庫の全文章が下記のように形態素解析済のデータが格納されています。87701673行、ファイルサイズは約6GB。 1000_15021.html,1,1,一,名詞,数,,,,,一,イチ,イチ 1000_15021.html,2,1,「,記号,括弧開,,,,,「,「,「 1000_15021.html,2,2,むかし,名詞,副詞可能,,,,,むかし,ムカシ,ムカシ 1000_15021.html,2,3,者,名詞,接尾,一般,,,,者,シャ,シャ 1000_15021.html,2,4,の,助詞,連体化,,,,,の,ノ,ノ 1000_15021.html,2,5,お話,名詞,サ変接続,,,,,お話,オハナシ,オハナシ 1000_15021.html,2,6,は,助詞,係助詞,,,,,は,ハ,ワ 1000_15021.html,2,7,とかく,名詞,副詞可能,,,,,とかく,トカク,トカク 1000_15021.html,2,8,前置き,名詞,サ変接続,,,,,前置き,マエオキ,マエオキ 1000_15021.html,2,9,が,助詞,格助詞,一般,,,,が,ガ,ガ 1000_15021.html,2,10,長い,形容詞,自立,,,形容詞・アウオ段,基本形,長い,ナガイ,ナガイ 1000_15021.html,2,11,ので,助詞,接続助詞,,,,,ので,ノデ,ノデ 1000_15021.html,2,12,、,記号,読点,,,,,、,、,、 1000_15021.html,2,13,今,名詞,副詞可能,,,,,今,イマ,イマ 1000_15021.html,2,14,の,助詞,連体化,,,,,の,ノ,ノ 1000_15021.html,2,15,若い,形容詞,自立,,,形容詞・アウオ段,基本形,若い,ワカイ,ワカイ 1000_15021.html,2,16,方,名詞,接尾,特殊,,,,方,カタ,カタ 1000_15021.html,2,17,たち,名詞,接尾,一般,,,,たち,タチ,タチ 1000_15021.html,2,18,に,助詞,格助詞,一般,,,,に,ニ,ニ 1000_15021.html,2,19,は,助詞,係助詞,,,,,は,ハ,ワ 1000_15021.html,2,20,小,名詞,一般,,,,,小,ショウ,ショー 1000_15021.html,2,21,焦れったい,形容詞,自立,,,形容詞・アウオ段,基本形,焦れったい,ジレッタイ,ジレッタイ 1000_15021.html,2,22,かも,助詞,副助詞,,,,,かも,カモ,カモ 1000_15021.html,2,23,知れ,動詞,自立,,,一段,連用形,知れる,シレ,シレ PostgreSQL側のテーブル作成 データ型はざっくりと。 CREATE TABLE aozora_kaiseki(file VARCHAR(30),num INT,row INT,word TEXT,subtype1 VARCHAR(30),subtype2 VARCHAR(30),subtype3 VARCHAR(30),subtype4 VARCHAR(10),conjtype VARCHAR(15),conjugation VARCHAR(15),basic TEXT,ruby TEXT,pronunce TEXT ); COPYコマンドでロード データをwgetで取得 wget http://aozora-word.hahasoha.net/utf8/utf8_all.csv.gz gzip -d utf8_all.csv.gz copyコマンドでロード psql -h rdspgsqlv1.xxxxxx.ap-northeast-1.rds.amazonaws.com -d postgres -U postgres -c "COPY aozora_kaiseki(file,num,row,word,subtype1,subtype2,subtype3,subtype4,conjtype,conjugation,basic,ruby,pronunce) from stdin with csv DELIMITER ','" < /home/ec2-user/utf8_all.csv 事後確認 約9.35GBのテーブルサイズでした。 postgres@rdspgsqlv1:postgres> select COUNT(*) from aozora_kaiseki; +----------+ | count | |----------| | 87701673 | +----------+ SELECT 1 Time: 78.574s (a minute), executed in: 78.562s (a minute) postgres@rdspgsqlv1:postgres> postgres@rdspgsqlv1:postgres> SELECT * FROM pgstattuple('aozora_kaiseki'); -[ RECORD 1 ]------------------------- table_len | 10039386112 tuple_count | 87701673 tuple_len | 9306566707 tuple_percent | 92.7 dead_tuple_count | 0 dead_tuple_len | 0 dead_tuple_percent | 0.0 free_space | 48754128 free_percent | 0.49 SELECT 1 Time: 21.117s (21 seconds), executed in: 21.111s (21 seconds) postgres@rdspgsqlv1:postgres> --- ### EC2(Amazon Linux)にpgcli(PostgreSQLの拡張CLI)をインストールする date: 2020-05-14 url: https://zatoima.github.io/aws-ec2-postgresql-pgcli-install-howto.html tags: AWS, PostgreSQL, RDS, Aurora, EC2 はじめに pgcliを使用してRDSやAuroraに接続したいので踏み台サーバへのEC2へインストールする。 pgcliはオートコンプリートと構文強調表示を備えたPostgres CLI。pipで簡単にインストール出来るかと思いきや意外とハマったのでメモしておく。 開発元は下記。 dbcli/pgcli: Postgres CLI with autocompletion and syntax highlighting https://github.com/dbcli/pgcli こちらの導入することで、下記のようにサジェストやハイライトシンタックスが出来るようになる。 インストール手順 githubやその他の導入ブログを見る限りpythonさえ入っていれば大丈夫なようだったが、下記ライブラリやパッケージが必要なことに注意が必要。 事前準備 sudo yum install -y python3 sudo pip3 install psycopg2-binary sudo yum -y install postgresql-devel sudo yum -y install gcc sudo yum -y install python3-devel.x86_64 インストール sudo pip3 install -U pgcli 接続 [ec2-user@bastin ~]$ pgcli -h rdspgsqlv1.xxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -U postgres -d postgres Server: PostgreSQL 10.7 Version: 3.0.0 Chat: https://gitter.im/dbcli/pgcli Home: http://pgcli.com postgres@rdspgsqlv1:postgres> 画面イメージ 以下はエラーの内容とエラー対応のメモ。エラー②とエラー③についてはローカルにPostgreSQLがインストールされている環境であれば既にインストールされているはずなのでエラーは起きないと思われる。 Python環境のインストール pip は Python 3.4 以降では Python 本体に同梱されるようなっているのでpip3の個別のインストールは不要。 sudo yum install -y python3 エラー①:psycopg2のエラー この状態でpgcliをインストールしてみる。 sudo pip3 install -U pgcli 下記のエラーが発生する。 Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-2mywyxn1/psycopg2/ psycopg2-binary をyumでインストールする。 sudo pip3 install psycopg2-binary エラー②:pg_configのエラー 次に実行するとpg_configに関連するエラーが発生 Error: pg_config executable not found. pg_config is required to build psycopg2 from source. Please add the directory containing pg_config to the $PATH or specify the full executable path with the option: python setup.py build_ext --pg-config /path/to/pg_config build ... or with the pg_config option in 'setup.cfg'. postgresql-develの中にpg_configが含まれているのでインストール。 sudo yum -y install postgresql-devel エラー③:gccのエラー gccが見つからずにエラー。 unable to execute 'gcc': No such file or directory It appears you are missing some prerequisite to build the package from source. You may install a binary package by installing 'psycopg2-binary' from PyPI. If you want to install psycopg2 from source, please install the packages required for the build and try again. gccをインストール sudo yum -y install gcc エラー④:python系のエラー ./psycopg/psycopg.h:35:10: fatal error: Python.h: No such file or directory #include <Python.h> ^~~~~~~~~~ compilation terminated. It appears you are missing some prerequisite to build the package from source. You may install a binary package by installing 'psycopg2-binary' from PyPI. If you want to install psycopg2 from source, please install the packages required for the build and try again. python3-devel.x86_64をインストール sudo yum -y install python3-devel.x86_64 pgcliのインストール ここまでインストールしてようやくpgcliのインストールが完了した。 [ec2-user@bastinv1 ~]$ sudo pip3 install -U pgcli WARNING: Running pip install with root privileges is generally not a good idea. Try `pip3 install --user` instead. Collecting pgcli ~中略~ Running setup.py install for psycopg2 ... done Running setup.py install for setproctitle ... done Successfully installed cli-helpers-1.2.1 click-7.1.2 humanize-2.4.0 pgcli-3.0.0 pgspecial-1.11.10 prompt-toolkit-3.0.5 psycopg2-2.8.5 setproctitle-1.1.10 tabulate-0.8.7 terminaltables-3.1.0 wcwidth-0.1.9 --- ### Neptuneへのバルクロード実行時に圧縮ファイルを使用する date: 2020-05-12 url: https://zatoima.github.io/aws-neptune-bulkload-from-s3-gzip.html tags: AWS, Neptune 目的 gzip形式の圧縮ファイルをサポートしているとあったので、単純な興味からS3からのNeptuneへのバルクロードの時間比較をしてみた。 ロードデータ形式 - Amazon Neptune https://docs.aws.amazon.com/ja_jp/neptune/latest/userguide/bulk-load-tutorial-format.html Neptune は、gzip 形式の単一ファイルの圧縮をサポートしています。ファイル名には .gz 拡張子を付ける必要があり、UTF-8 形式でエンコードされた単一のテキストファイルを含む必要があります。複数のファイルをロードできますが、それぞれは個別の .gz ファイル (非圧縮のテキストファイル) に含まれている必要があります。アーカイブファイル (例: .tar、.tar.gz、および .tgz) はサポートされていません。 ちなみに、Redshiftへのロード時の圧縮ファイルと非圧縮ファイルの差異はこんな感じらしい。(この記事を見てNeptuneではどうなのか?が気になった。) 【新機能】Redshift COPY/UNLOADのBZIP2ファイル対応を試してみました | Developers.IO https://dev.classmethod.jp/articles/amazon-redshift-bzip2-support/#toc-4 前提 db.r5.4xlargeで実行。parallelism ではHIGHを指定。特に指定しなくてもデフォルトはHIGHで動作する。HIGHの場合のCPU使用率は80%~100%で推移をしていた。 https://docs.aws.amazon.com/ja_jp/neptune/latest/userguide/load-api-reference-load.html > Neptune ローダーのリクエストパラメータ LOW – 使用されるスレッドの数は、コア数を 8 で割った値です。 MEDIUM – 使用されるスレッドの数は、コア数を 2 で割った値です。 HIGH – 使用されるスレッドの数は、コア数と同じです。 OVERSUBSCRIBE – 使用されるスレッドの数は、コア数に 2 を乗算した値です。この値を使用する場合、バルクローダーは利用可能なすべてのリソースを消費します。 結果 トリプル数が1000万件だと有意な差異が無かった。一方1億トリプルの場合はデータロード時間に150秒の差異が出た。 パラレリズム 圧縮 データロード データ削除(drop all) 1000万トリプル HIGH 非圧縮 139秒 420秒 1000万トリプル HIGH 圧縮 140秒 417秒 1億トリプル HIGH 非圧縮 1169秒 4866秒 1億トリプル HIGH 圧縮 1303秒 4844秒 CPU使用率はparallelism をHIGHで実行していることもあって、ロード実行時はは80%~100%の間で推移していた。データ削除はdrop allで実行したが、こちらの場合はシングルスレッドでdropしているためか約20%で推移をしていた。 なお、ロード時間を短くするためには下記のベストプラクティスのページにもある通り、一時的にスケールアップした上でロードするのが良い。その分パラレル化されてロード時間が短くなる。 Amazon Neptune の基本的な運用についてのガイドライン - Amazon Neptune https://docs.aws.amazon.com/ja_jp/neptune/latest/userguide/best-practices-general-basic.html#best-practices-loader-tempinstance 一時的に大きなインスタンスを使用してロード時間を短縮 実行時のコマンドと結果 以下は実行した際のコマンドと実行結果を参考までに。 1000万件のトリプル(非圧縮) S3からのバルクロード curl -X POST \ -H 'Content-Type: application/json' \ https://xxxxxxxxx.xxxxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/loader -d ' { "source" : "s3://xxxxxxxxxx/non-compression/rdf-test.nq", "format" : "nquads", "iamRoleArn" : "arn:aws:iam::xxxxxxxxxx:role/NeptuneLoadFromS3", "region" : "ap-northeast-1", "failOnError" : "FALSE", "parallelism" : "HIGH" }' S3からのバルクロードのステータス確認 curl -G 'https://xxxxxxxxx.xxxxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/loader/4b197f60-9239-4ab3-8b21-6a320930df51' { "status" : "200 OK", "payload" : { "feedCount" : [ { "LOAD_COMPLETED" : 1 } ], "overallStatus" : { "fullUri" : "s3://xxxxxxxxxx/non-compression/rdf-test.nq", "runNumber" : 1, "retryNumber" : 0, "status" : "LOAD_COMPLETED", "totalTimeSpent" : 139, "startTime" : 1588592100, "totalRecords" : 10000000, "totalDuplicates" : 0, "parsingErrors" : 0, "datatypeMismatchErrors" : 0, "insertErrors" : 0 } } } データ削除 curl -X POST --data-binary 'update=drop all' https://xxxxxxxxx.xxxxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/sparql [ { "type" : "UpdateEvent", "totalElapsedMillis" : 420916, "elapsedMillis" : 420915, "connFlush" : 0, "batchResolve" : 0, "whereClause" : 0, "deleteClause" : 0, "insertClause" : 0 }, { "type" : "Commit", "totalElapsedMillis" : 421169 } ] 1000万件のトリプル(圧縮) S3からのバルクロード curl -X POST \ -H 'Content-Type: application/json' \ https://xxxxxxxxx.xxxxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/loader -d ' { "source" : "s3://xxxxxxxxxx/compression/rdf-test.nq.gz", "format" : "nquads", "iamRoleArn" : "arn:aws:iam::xxxxxxxxxx:role/NeptuneLoadFromS3", "region" : "ap-northeast-1", "failOnError" : "FALSE", "parallelism" : "HIGH" }' S3からのバルクロードのステータス確認 curl -G 'https://xxxxxxxxx.xxxxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/loader/f1e8303c-077b-44f8-a6f2-c1b65a6f61e6' { "status" : "200 OK", "payload" : { "feedCount" : [ { "LOAD_COMPLETED" : 1 } ], "overallStatus" : { "fullUri" : "s3://xxxxxxxxxx/compression/rdf-test.nq.gz", "runNumber" : 1, "retryNumber" : 0, "status" : "LOAD_COMPLETED", "totalTimeSpent" : 140, "startTime" : 1588592750, "totalRecords" : 10000000, "totalDuplicates" : 0, "parsingErrors" : 0, "datatypeMismatchErrors" : 0, "insertErrors" : 0 } } } データ削除 curl -X POST --data-binary 'update=drop all' https://xxxxxxxxx.xxxxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/sparql [ { "type" : "UpdateEvent", "totalElapsedMillis" : 417666, "elapsedMillis" : 417665, "connFlush" : 0, "batchResolve" : 0, "whereClause" : 0, "deleteClause" : 0, "insertClause" : 0 }, { "type" : "Commit", "totalElapsedMillis" : 417913 } ] 1億件のトリプル(非圧縮) S3からのバルクロード curl -X POST \ -H 'Content-Type: application/json' \ https://xxxxxxxxx.xxxxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/loader -d ' { "source" : "s3://xxxxxxxxxx/non-compression/neptune-load.nq", "format" : "nquads", "iamRoleArn" : "arn:aws:iam::xxxxxxxxxx:role/NeptuneLoadFromS3", "region" : "ap-northeast-1", "failOnError" : "FALSE", "parallelism" : "HIGH" }' S3からのバルクロードのステータス確認 curl -G 'https://xxxxxxxxx.xxxxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/loader/56d84748-5b1c-4ff6-945c-15899da10c62' { "status" : "200 OK", "payload" : { "feedCount" : [ { "LOAD_COMPLETED" : 1 } ], "overallStatus" : { "fullUri" : "s3://xxxxxxxxxx/non-compression/neptune-load.nq", "runNumber" : 1, "retryNumber" : 0, "status" : "LOAD_COMPLETED", "totalTimeSpent" : 1169, "startTime" : 1588594197, "totalRecords" : 100000000, "totalDuplicates" : 0, "parsingErrors" : 0, "datatypeMismatchErrors" : 0, "insertErrors" : 0 } } } データ削除 curl -X POST --data-binary 'update=drop all' https://xxxxxxxxx.xxxxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/sparql [ { "type" : "UpdateEvent", "totalElapsedMillis" : 4866624, "elapsedMillis" : 4866623, "connFlush" : 0, "batchResolve" : 0, "whereClause" : 0, "deleteClause" : 0, "insertClause" : 0 }, { "type" : "Commit", "totalElapsedMillis" : 4871394 } ] 1億件のトリプル(圧縮) S3からのバルクロード curl -X POST \ -H 'Content-Type: application/json' \ https://xxxxxxxxx.xxxxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/loader -d ' { "source" : "s3://xxxxxxxxxx/compression/neptune-load.nq.gz", "format" : "nquads", "iamRoleArn" : "arn:aws:iam::xxxxxxxxxx:role/NeptuneLoadFromS3", "region" : "ap-northeast-1", "failOnError" : "FALSE", "parallelism" : "HIGH" }' S3からのバルクロードのステータス確認 curl -G 'https://xxxxxxxxx.xxxxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/loader/b7e34c0c-bf49-42d6-885b-34e58fed19c0' { "status" : "200 OK", "payload" : { "feedCount" : [ { "LOAD_COMPLETED" : 1 } ], "overallStatus" : { "fullUri" : "s3://xxxxxxxxxx/compression/neptune-load.nq.gz", "runNumber" : 1, "retryNumber" : 0, "status" : "LOAD_COMPLETED", "totalTimeSpent" : 1303, "startTime" : 1588600418, "totalRecords" : 100000000, "totalDuplicates" : 0, "parsingErrors" : 0, "datatypeMismatchErrors" : 0, "insertErrors" : 0 } } } データ削除 curl -X POST --data-binary 'update=drop all' https://xxxxxxxxx.xxxxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/sparql [ { "type" : "UpdateEvent", "totalElapsedMillis" : 4844456, "elapsedMillis" : 4844455, "connFlush" : 0, "batchResolve" : 0, "whereClause" : 0, "deleteClause" : 0, "insertClause" : 0 }, { "type" : "Commit", "totalElapsedMillis" : 4848418 } ] --- ### Amazon CloudWatchのメトリクスをCSVで出力する date: 2020-05-10 url: https://zatoima.github.io/aws-cloudwatch-csv-export-command.html tags: AWS, CloudWatch 前提 jqを使用するのでyum等で別途インストールが必要。 sudo yum -y install jq コマンド aws cloudwatch get-metric-statistics --namespace AWS/Neptune --metric-name VolumeBytesUsed --start-time 2020-05-06T00:00:00 --end-time 2020-05-07T12:00:00 --period 300 --statistics Average --dimensions Name=DBClusterIdentifier,Value=neploadtest1 | jq -r '.Datapoints[] | [ .Timestamp ,.Average ,.Unit] | @csv' | sort -t ',' -k 1 結果 [ec2-user@bastin ~]$ aws cloudwatch get-metric-statistics --namespace AWS/Neptune --metric-name VolumeBytesUsed --start-time 2020-05-06T00:00:00 --end-time 2020-05-07T12:00:00 --period 300 --statistics Average --dimensions Name=DBClusterIdentifier,Value=neploadtest1 | jq -r '.Datapoints[] | [ .Timestamp ,.Average ,.Unit] | @csv' | sort -t ',' -k 1 "2020-05-06T06:05:00Z",0,"Bytes" "2020-05-06T06:15:00Z",126189568,"Bytes" "2020-05-06T06:20:00Z",24679677952,"Bytes" "2020-05-06T06:25:00Z",24679677952,"Bytes" "2020-05-06T06:30:00Z",24679677952,"Bytes" "2020-05-06T06:35:00Z",35896573952,"Bytes" "2020-05-06T06:40:00Z",35896573952,"Bytes" "2020-05-06T06:45:00Z",35896573952,"Bytes" "2020-05-06T06:50:00Z",55787798528,"Bytes" "2020-05-06T06:55:00Z",55787798528,"Bytes" "2020-05-06T07:00:00Z",64544718848,"Bytes" "2020-05-06T07:05:00Z",64544718848,"Bytes" "2020-05-06T07:10:00Z",64544718848,"Bytes" "2020-05-06T07:15:00Z",64546799616,"Bytes" "2020-05-06T07:20:00Z",64546799616,"Bytes" "2020-05-06T07:25:00Z",64546799616,"Bytes" "2020-05-06T07:30:00Z",76659359744,"Bytes" "2020-05-06T07:35:00Z",76659359744,"Bytes" "2020-05-06T07:40:00Z",92551282688,"Bytes" "2020-05-06T07:45:00Z",92551282688,"Bytes" "2020-05-06T07:50:00Z",92551282688,"Bytes" "2020-05-06T07:55:00Z",93257973760,"Bytes" --- ### Neptuneで実行中のクエリを確認する date: 2020-05-07 url: https://zatoima.github.io/aws-neptune-execute-query-check.html tags: Neptune 特定のクエリを実行した場合に下記のようなエラーが発生する場合がある。原因は処理の競合。 { "requestId": "c4b8f484-2de1-b8a4-81dd-6b225981653f", "code": "ConcurrentModificationException", "detailedMessage": "Operation failed due to conflicting concurrent operations (please retry), 0 transactions are currently rolling back." } 他にどんなクエリが流れているか確認したい場合にはSPARQL クエリステータス APIを使用。queryStringが実際に流れているSPARQLクエリとなる。 [ec2-user@bastin ~]$ curl https://xxxxxxxx.xxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/sparql/status | jq % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 205 0 205 0 0 9318 0 --:--:-- --:--:-- --:--:-- 9318 { "acceptedQueryCount": 8, "runningQueryCount": 1, "queries": [ { "queryId": "372954e5-f674-497e-ae1f-0d772e636e41", "queryEvalStats": { "subqueries": 0, "elapsed": 1034223, "cancelled": false }, "queryString": "clear all" } ] } 参考 SPARQL クエリステータス API - Amazon Neptune https://docs.aws.amazon.com/ja_jp/neptune/latest/userguide/sparql-api-status.html --- ### Elasticsearchの個人的によく使うコマンド集 date: 2020-05-05 url: https://zatoima.github.io/aws-elasticsearch-commands-lists.html tags: AWS, Elasticsearch Amazon Elasticsearch Service 上でのコマンド実行を想定。適宜追加。 インデックス作成 curl -X PUT "<Amazon Elasticsearch Serviceのエンドポイント>/<index_name>" インデックスの確認 curl <Amazon Elasticsearch Serviceのエンドポイント>/_aliases?pretty インデックスの詳細確認 curl <Amazon Elasticsearch Serviceのエンドポイント>/<index_name>/_settings?pretty インデックス削除 curl -XDELETE <Amazon Elasticsearch Serviceのエンドポイント>/<index_name>?pretty=true データ検索(無条件) curl <Amazon Elasticsearch Serviceのエンドポイント>/<index_name>/_search?pretty index確認 curl <Amazon Elasticsearch Serviceのエンドポイント>/_cat/indices?v 件数確認 curl <Amazon Elasticsearch Serviceのエンドポイント>/_cat/count/<index_name>?v curl <Amazon Elasticsearch Serviceのエンドポイント>/<index_name>/_count?pretty 統計情報 curl <Amazon Elasticsearch Serviceのエンドポイント>/<index_name>/_stats?pretty エイリアスの確認 curl <Amazon Elasticsearch Serviceのエンドポイント>/_aliases?pretty エイリアスの作成 curl -H "Content-Type: application/json" -XPOST '<Amazon Elasticsearch Serviceのエンドポイント>/_aliases' -d ' { "actions" : [ { "add" : { "index" : "my_index1", "alias" : "my_ind1" } }, { "add" : { "index" : "my_index2", "alias" : "my_ind2" } } ] }' エイリアスの削除 curl -H "Content-Type: application/json" -XPOST '<Amazon Elasticsearch Serviceのエンドポイント>/_aliases' -d ' { "actions" : [ { "remove" : { "index" : "my_index1", "alias" : "my_ind1" } }, { "remove" : { "index" : "my_index2", "alias" : "my_ind2" } } ] }' catで確認が可能なもの一覧 curl <Amazon Elasticsearch Serviceのエンドポイント>/_cat マッピング確認 curl <Amazon Elasticsearch Serviceのエンドポイント>/<index_name>/_mapping?pretty 各ノードの役割の確認 curl <Amazon Elasticsearch Serviceのエンドポイント>/_cat/nodes マスターノードの確認 curl <Amazon Elasticsearch Serviceのエンドポイント>/_cat/master どのノードがどのシャードを含んでいるか確認 curl <Amazon Elasticsearch Serviceのエンドポイント>/_cat/shards field-dataの確認 curl -XGET <Amazon Elasticsearch Serviceのエンドポイント>/_stats/fielddata?pretty --- ### Elasticsearchのエイリアス設定方法 date: 2020-05-04 url: https://zatoima.github.io/aws-elasticsearch-alias-setting.html tags: AWS, Elasticsearch AWS上のAmazon Elasticsearch Serviceで実施しています。 エイリアスとは名前の通り、インデックスに対して別名をつけることが可能になる。エイリアスとインデックスは1対1の関係ではなく、一つのエイリアスに複数のインデックスを紐付けることが出来る。 インデックスの作成 まずは事前準備としてインデックスを作成。 curl -X PUT "https://vpc-xxxxxxxx-xxxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com/my_index1" curl -X PUT "https://vpc-xxxxxxxx-xxxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com/my_index2" データ登録(my_index1用) 後ほどエイリアスを使用した検索を実施するのでテスト用のデータを挿入 curl -H "Content-Type: application/json" -X PUT "https://vpc-xxxxxxxx-xxxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com/my_index1/_doc/1" -d ' { "title": "my_index1", "comments": { "name": "my_index1", "comment": "my_index1用のデータ" } }' データ登録(my_index2用) curl -H "Content-Type: application/json" -X PUT "https://vpc-xxxxxxxx-xxxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com/my_index2/_doc/1" -d ' { "title": "my_index2", "comments": { "name": "my_index2", "comment": "my_index2のデータ" } }' エイリアスの確認 cu 初期状態なので特にエイリアスは設定されていない { "amazon_neptune" : { "aliases" : { } }, ".kibana_1" : { "aliases" : { ".kibana" : { } } }, "my_index2" : { "aliases" : { } }, "my_index1" : { "aliases" : { } } } エイリアスの作成 my_index1のエイリアスであるmy_indを作成してみる curl -H "Content-Type: application/json" -XPOST 'https://vpc-xxxxxxxx-xxxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com/_aliases' -d ' { "actions" : [ { "add" : { "index" : "my_index1", "alias" : "my_ind" } } ] }' エイリアスの確認 curl https://vpc-xxxxxxxx-xxxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com/_aliases?pretty my_indが作成されている "my_index2" : { "aliases" : { } }, "my_index1" : { "aliases" : { "my_ind" : { } } この状態で検索をしてみるとmy_index1用のデータが出力される。 curl https://vpc-xxxxxxxx-xxxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com/my_ind/_search?pretty エイリアスの変更 次にエイリアスの設定変更をすることでインデックスの切替を実施する curl -H "Content-Type: application/json" -XPOST 'https://vpc-xxxxxxxx-xxxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com/_aliases' -d ' { "actions" : [ { "remove" : { "index" : "my_index1", "alias" : "my_ind" } }, { "add" : { "index" : "my_index2", "alias" : "my_ind" } } ] }' エイリアスの確認 curl https://vpc-xxxxxxxx-xxxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com/_aliases?pretty 先程とは異なりmy_index2用のエイリアスが作成されている。my_index1のエイリアスは削除され存在しない。 "my_index2" : { "aliases" : { "my_ind" : { } } }, "my_index1" : { "aliases" : { } } エイリアスを使用した検索 curl https://vpc-xxxxxxxx-xxxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com/my_ind/_search?pretty このエイリアス機能を使用することでダウンタイムを無くしてインデックスの切替が実施出来る。 Changing Mapping with Zero Downtime | Elastic Blog https://www.elastic.co/jp/blog/changing-mapping-with-zero-downtime/ Elasticsearch のインデックスを無停止で再構築する - クックパッド開発者ブログ https://techlife.cookpad.com/entry/2015/09/25/170000 --- ### PostgreSQL上のnumeric型とint型の性能差 date: 2020-05-02 url: https://zatoima.github.io/postgresql-compare-performance-numeric-integer.html tags: PostgreSQL PostgreSQLのマニュアルを見ていたらこんな記載が。 8.1. 数値データ型 https://www.postgresql.jp/document/11/html/datatype-numeric.html numericの値に対する計算は整数型、もしくは次節で説明する浮動小数点データ型に比較し非常に遅くなります。 どのくらいの差が生じるのか気になったので実機で確認してみた。 numericのテーブル作成 CREATE TABLE t1(id numeric primary key,num text,data numeric,date timestamp with time zone); postgres=> \d t1; Table "public.t1" Column | Type | Collation | Nullable | Default --------+--------------------------+-----------+----------+--------- id | numeric | | not null | num | text | | | data | numeric | | | date | timestamp with time zone | | | Indexes: "t1_pkey" PRIMARY KEY, btree (id) integerのテーブル作成 CREATE TABLE t1(id numeric primary key,num text,data integer,date timestamp with time zone); postgres=# \d t1; Table "public.t1" Column | Type | Collation | Nullable | Default --------+--------------------------+-----------+----------+--------- id | numeric | | not null | num | text | | | data | integer | | | date | timestamp with time zone | | | Indexes: "t1_pkey" PRIMARY KEY, btree (id) データの大量生成(5000万件) truncate table t1; insert into t1 SELECT num a ,'1' b ,floor(random() * 1000000) c ,current_timestamp d FROM generate_series(1,50000000) num ; 余計な負荷が掛からないようにtimingで計測する。パラレルクエリで走らないようにパラメータを調整する。 \timing SET max_parallel_workers_per_gather TO 0; SELECT SUM(data) FROM t1; SELECT AVG(data) FROM t1; SELECT STDDEV(data) FROM t1; キャッシュの影響を受けないように、念の為PostgreSQLの再起動とファイルシステム側のキャッシュのクリアをしている。 pg_ctl stop sudo "echo 3 > /proc/sys/vm/drop_caches" pg_ctl start 結果 回数が少ないので何とも言えないがこんな結果に。データ型の検討時には注意をしよう。 numeric integer 性能差 SUM 9403.565 8508.652 0.904833 AVG 8590.127 8886.078 1.034452 STDDEV 12419.859 8325.705 0.670354 --- ### Elasticsearchのマスターノードの確認 date: 2020-04-29 url: https://zatoima.github.io/aws-elasticsearch-masternode-check.html tags: AWS, Elasticsearch 各ノードの役割の確認 diがデータノードで、mがマスターノード候補。その中でアスタリスクがついているのが現在動作しているマスターノード。 コマンド curl https://vpc-xxxxxxxxx-xxxxxxxxx.ap-northeast-1.es.amazonaws.com/_cat/nodes 実行結果 [ec2-user@bastin ~]$ curl https://vpc-xxxxxxxxx-xxxxxxxxx.ap-northeast-1.es.amazonaws.com/_cat/nodes x.x.x.x 14 84 7 0.56 0.34 0.14 di - d80e9ad21a626ddb1cd444cf42921a08 x.x.x.x 11 87 6 0.10 0.07 0.02 m - dd1a87f44380da342e4e72c3195e0ebd x.x.x.x 15 86 0 0.22 0.13 0.06 m * 73cde264f7a37e9ca4b5b95ae7f69565 x.x.x.x 15 87 0 0.05 0.06 0.02 m - 9fc04f6429d0471cdfd8e31b0ab73f46 x.x.x.x 14 84 1 0.22 0.18 0.06 di - 2245efa92445b06e79699db2acd06091 マスターノードの確認 コマンド curl https://vpc-xxxxxxxxx-xxxxxxxxx.ap-northeast-1.es.amazonaws.com/_cat/master 実行結果 [ec2-user@bastin ~]$ curl https://vpc-xxxxxxxxx-xxxxxxxxx.ap-northeast-1.es.amazonaws.com/_cat/master V9KHonTYTWOtt4vsGs2NBw x.x.x.x x.x.x.x 73cde264f7a37e9ca4b5b95ae7f69565 --- ### Aurora PostgreSQL でリードレプリカかプライマリか見分ける方法 date: 2020-04-25 url: https://zatoima.github.io/aws-aurora-replica-master-check.html tags: AWS, Aurora, PostgreSQL server_id に session_id='MASTER_SESSION_ID' があればプライマリのインスタンス。 postgres=> select server_id,session_id,highest_lsn_rcvd,cur_replay_latency_in_usec,now(),last_update_timestamp from aurora_replica_status(); server_id | session_id | highest_lsn_rcvd | cur_replay_latency_in_usec | now | last_update_timestamp -------------------+-------------------+------------------+----------------------------+-------------------------------+------------------------ aurorapostgresv11 | MASTER_SESSION_ID | | | 2020-04-24 13:44:30.808061+00 | 2020-04-24 13:44:29+00 (1 row) https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.BestPractices.html > ホスト文字列を取得するそのほかのオプション アプリケーションは、DB クラスターのすべての DB インスタンスに接続でき、aurora_replica_status 関数を照会して、クラスターのライターを特定したり、クラスターのその他のリーダーノードを見つけたりできます。 --- ### PostgreSQL上のバッファキャッシュをクリアする方法 date: 2020-04-24 url: https://zatoima.github.io/postgresql-buffercache-clear.html tags: PostgreSQL PostgreSQLにはOracleのようにバッファキャッシュをクリアにする方法は用意されていないので、OS上のファイルシステムをクリアにするしかない。なので件名のPostgreSQL上のバッファキャッシュをクリアにするという表現は正しくなく、OS上のキャッシュをクリアにする方法となる。 pg_ctl stop sudo su - -c "echo 3 > /proc/sys/vm/drop_caches" pg_ctl start 参考: [pgsql-jp: 40643] Re: PostgreSQLキャッシュクリア方法についてご質問 https://ml.postgresql.jp/pipermail/pgsql-jp/2010-December/015599.html --- ### LGモニターのOnScreen Controlのダウンロード方法 date: 2020-04-18 url: https://zatoima.github.io/tips-lg-monitor-onscreencontrol-download.html tags: LG, Tips LG モニター 34WL500-B を買いました! OnScreen Controlというモニターの管理ソフトウェアがあるのですが、ダウンロード可能なリンク先がよくわからず、少し時間が掛かってしまったので一応メモしておく。 成功パターン OnScreen Control で検索するとダウンロードリンクが出てくるのでOSに合わせたソフトウェアをダウンロード出来る。 https://www.lg.com/jp/search.lg?search=OnScreen+Control 下記はおまけ。 失敗パターン① ここのリンクから飛んでみる。 https://www.lg.com/jp/monitor/OSC 何故かログインページに飛ばされる。 失敗パターン② 製品個別ページのリンクから飛ぶ https://www.lg.com/jp/business-monitor/lg-34WL500-B 失敗パターン① のページに飛ぶ 失敗パターン③ 製品個別ページのリンクから飛ぶ https://www.lg.com/jp/business-monitor/lg-34WL500-B 特に検索結果も見つからないし、ダウンロードページも見つからない。 --- ### EC2にElasticsearch + kibanaをインストールする date: 2020-04-17 url: https://zatoima.github.io/aws-ec2-elasticsearch-install.html tags: AWS EC2にElasticsearchをインストールして満足するだけのメモ。 javaのインストール sudo -s sudo yum install java-1.8.0-openjdk.x86_64 java -version Elasicsearchのインストール yum でインストールするためにリポジトリの設定 cat > /etc/yum.repos.d/elasticsearch.repo <<EOF [elasticsearch-7.x] name=Elasticsearch repository for 7.x packages baseurl=https://artifacts.elastic.co/packages/7.x/yum gpgcheck=1 gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch enabled=1 autorefresh=1 type=rpm-md EOF Elasitcserchのインストール yum -y install elasticsearch Elasticsearchの起動 systemctl start elasticsearch systemctl status elasticsearch 永続設定 systemctl enable elasticsearch インストール確認 Elasicsearchの7.6.1がインストールされています。 [root@elastic ec2-user]# curl http://127.0.0.1:9200 { "name" : "elastic", "cluster_name" : "elasticsearch", "cluster_uuid" : "YWsoyak7S9SOTOXJp92_QQ", "version" : { "number" : "7.6.1", "build_flavor" : "default", "build_type" : "rpm", "build_hash" : "aa751e09be0a5072e8570670309b1f12348f023b", "build_date" : "2020-02-29T00:15:25.529771Z", "build_snapshot" : false, "lucene_version" : "8.4.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" } kuromojiのインストール [root@elastic ec2-user]# /usr/share/elasticsearch/bin/elasticsearch-plugin install analysis-kuromoji -> Installing analysis-kuromoji -> Downloading analysis-kuromoji from elastic [=================================================] 100% -> Installed analysis-kuromoji [root@elastic ec2-user]# /usr/share/elasticsearch/bin/elasticsearch-plugin list analysis-kuromoji [root@elastic ec2-user]# kibanaのインストール yum -y install kibana 設定変更 server.hostを0.0.0.0に変更 vi /etc/kibana/kibana.yml kibana起動 systemctl start kibana systemctl status kibana 起動しました。 [root@elastic ec2-user]# systemctl status kibana ● kibana.service - Kibana Loaded: loaded (/etc/systemd/system/kibana.service; disabled; vendor preset: disabled) Active: active (running) since Sun 2020-03-22 11:33:46 UTC; 40s ago Main PID: 3471 (node) CGroup: /system.slice/kibana.service └─3471 /usr/share/kibana/bin/../node/bin/node /usr/share/kibana/bin/../src/cli -c /etc/kibana/kibana.yml Mar 22 11:34:15 elastic kibana[3471]: {"type":"log","@timestamp":"2020-03-22T11:34:15Z","tags":["status","plugin:ui_metric@7.6.1","info"],"pid":3471,"state":"green","message...nitialized"} Mar 22 11:34:15 elastic kibana[3471]: {"type":"log","@timestamp":"2020-03-22T11:34:15Z","tags":["status","plugin:markdown_vis@7.6.1","info"],"pid":3471,"state":"green","mess...nitialized"} Mar 22 11:34:15 elastic kibana[3471]: {"type":"log","@timestamp":"2020-03-22T11:34:15Z","tags":["status","plugin:metric_vis@7.6.1","info"],"pid":3471,"state":"green","messag...nitialized"} Mar 22 11:34:15 elastic kibana[3471]: {"type":"log","@timestamp":"2020-03-22T11:34:15Z","tags":["status","plugin:table_vis@7.6.1","info"],"pid":3471,"state":"green","message...nitialized"} Mar 22 11:34:15 elastic kibana[3471]: {"type":"log","@timestamp":"2020-03-22T11:34:15Z","tags":["status","plugin:tagcloud@7.6.1","info"],"pid":3471,"state":"green","message"...nitialized"} Mar 22 11:34:15 elastic kibana[3471]: {"type":"log","@timestamp":"2020-03-22T11:34:15Z","tags":["status","plugin:vega@7.6.1","info"],"pid":3471,"state":"green","message":"St...nitialized"} Mar 22 11:34:17 elastic kibana[3471]: {"type":"log","@timestamp":"2020-03-22T11:34:17Z","tags":["reporting","warning"],"pid":3471,"message":"Generating a random key for xpac...kibana.yml"} Mar 22 11:34:17 elastic kibana[3471]: {"type":"log","@timestamp":"2020-03-22T11:34:17Z","tags":["status","plugin:reporting@7.6.1","info"],"pid":3471,"state":"green","message...nitialized"} Mar 22 11:34:17 elastic kibana[3471]: {"type":"log","@timestamp":"2020-03-22T11:34:17Z","tags":["listening","info"],"pid":3471,"message":"Server running at http://0.0.0.0:5601"} Mar 22 11:34:18 elastic kibana[3471]: {"type":"log","@timestamp":"2020-03-22T11:34:18Z","tags":["info","http","server","Kibana"],"pid":3471,"message":"http server running at...0.0.0:5601"} Hint: Some lines were ellipsized, use -l to show in full. kibanaの起動永続設定 Elasticsearchと同様に再起動後に自動でkibanaが起動されるように設定を行います。 systemctl enable kibana 以上! --- ### PostgreSQLのpg_basebackupを使用してバックアップ/リカバリを行う date: 2020-04-12 url: https://zatoima.github.io/postgresql-pg_basebackup-backup-recovery.html tags: PostgreSQL pg_basebackupを使ったPostgreSQLの基本的なバックアップ/リカバリを実施する。 バックアップ バックアップディレクトリの作成 mkdir $HOME/pg_basebackup_dir 環境変数の設定 export BACKUP_DIR=/var/lib/pgsql/pg_basebackup_dir pg_basebackupでのバックアップ pg_basebackup -D $BACKUP_DIR -F t -z ls -l $BACKUP_DIR 今回は フォーマットでtarファイルを指定してしており、かつtarファイル出力のデフォルトの圧縮レベルによるgzip圧縮を有効にしている。 pg_basebackup https://www.postgresql.jp/document/10/html/app-pgbasebackup.html データ損失 DB停止 pg_ctl stop データ削除 物理的にデータを損失させる。 rm -r /var/lib/pgsql/10/data/* リカバリ ここからがリカバリ。 バックアップデータの展開 cd /var/lib/pgsql/10/data tar xvfz $BACKUP_DIR/base.tar.gz pg_walの削除 rm -rf /var/lib/pgsql/10/data/pg_wal/* バックアップしたwalファイルの解凍 cd /var/lib/pgsql/10/data/pg_wal tar xvfz $BACKUP_DIR/pg_wal.tar.gz バックアップしたwalファイルの解凍 cd /var/lib/pgsql/10/data/pg_wal tar xvfz $BACKUP_DIR/pg_wal.tar.gz recovery.confファイルの作成 cd /var/lib/pgsql/10/data/ vi /var/lib/pgsql/10/data/recovery.conf restore_command = 'cp /var/lib/pgsql/10/data/pg_wal/%f %p' デフォルトではリカバリ可能な最新時点までリカバリされるが、PITRなど時間を明示的に指定したい場合は下記マニュアルを参考にしつつrecovery_target_nameやrecovery_target_lsnを設定する。 27.2. リカバリ対象の設定 https://www.postgresql.jp/document/10/html/recovery-target-settings.html DB起動 通常のコマンドと同様にスタートする。この時recovery.confを参照してリカバリを行う。 pg_ctl start リカバリ時のログ出力 [2020-03-04 13:34:00 UTC] 18052[1] LOG: database system was interrupted; last known up at 2020-03-04 13:31:23 UTC [2020-03-04 13:34:00 UTC] 18052[2] LOG: starting archive recovery [2020-03-04 13:34:00 UTC] 18052[3] LOG: restored log file "00000002.history" from archive [2020-03-04 13:34:00 UTC] 18052[4] LOG: restored log file "000000020000000000000050" from archive [2020-03-04 13:34:00 UTC] 18052[5] LOG: redo starts at 0/50000028 [2020-03-04 13:34:00 UTC] 18052[6] LOG: consistent recovery state reached at 0/500000F8 [2020-03-04 13:34:00 UTC] 18050[6] LOG: database system is ready to accept read only connections cp: cannot stat ‘/var/lib/pgsql/10/data/pg_wal/000000020000000000000051’: No such file or directory [2020-03-04 13:34:00 UTC] 18052[7] LOG: redo done at 0/500000F8 [2020-03-04 13:34:00 UTC] 18052[8] LOG: restored log file "000000020000000000000050" from archive cp: cannot stat ‘/var/lib/pgsql/10/data/pg_wal/00000003.history’: No such file or directory [2020-03-04 13:34:00 UTC] 18052[9] LOG: selected new timeline ID: 3 [2020-03-04 13:34:01 UTC] 18052[10] LOG: archive recovery complete [2020-03-04 13:34:01 UTC] 18052[11] LOG: restored log file "00000002.history" from archive [2020-03-04 13:34:01 UTC] 18055[1] LOG: checkpoint starting: end-of-recovery immediate wait [2020-03-04 13:34:01 UTC] 18055[2] LOG: checkpoint complete: wrote 0 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.000 s, sync=0.000 s, total=0.004 s; sync files=0, longest=0.000 s, average=0.000 s; distance=16384 kB, estimate=16384 kB [2020-03-04 13:34:01 UTC] 18050[7] LOG: database system is ready to accept connections cp: cannot create regular file ‘/var/lib/pgsql/10/data/pg_wal/archive/00000003.history’: No such file or directory [2020-03-04 13:34:01 UTC] 18064[1] LOG: archive command failed with exit code 1 [2020-03-04 13:34:01 UTC] 18064[2] DETAIL: The failed archive command was: cp pg_wal/00000003.history /var/lib/pgsql/10/data/pg_wal/archive/00000003.history cp: cannot create regular file ‘/var/lib/pgsql/10/data/pg_wal/archive/00000003.history’: No such file or directory [2020-03-04 13:34:02 UTC] 18064[3] LOG: archive command failed with exit code 1 [2020-03-04 13:34:02 UTC] 18064[4] DETAIL: The failed archive command was: cp pg_wal/00000003.history /var/lib/pgsql/10/data/pg_wal/archive/00000003.history cp: cannot create regular file ‘/var/lib/pgsql/10/data/pg_wal/archive/00000003.history’: No such file or directory [2020-03-04 13:34:03 UTC] 18064[5] LOG: archive command failed with exit code 1 [2020-03-04 13:34:03 UTC] 18064[6] DETAIL: The failed archive command was: cp pg_wal/00000003.history /var/lib/pgsql/10/data/pg_wal/archive/00000003.history [2020-03-04 13:34:03 UTC] 18064[7] WARNING: archiving write-ahead log file "00000003.history" failed too many times, will try again later --- ### Neptuneインスタンスの監査ログを取得する方法 date: 2020-04-07 url: https://zatoima.github.io/aws-neptune-audit-log.html tags: AWS, Neptune インスタンス作成時に監査ログの有効化をチェックしていたにも関わらず、監査ログが出ないなーと思っていたらAudit logging must be enabled for logs to be published in CloudWatch Logs. Please set the neptune_enable_audit_log parameter to enable (1) in the parameter group that is used in this database cluster.とあるようにパラメータの設定が必要だった模様。 監査ログが出力しないと思っていたら、neptune_enable_audit_logを「0」から「1」に変更する必要があり、適用タイプがstaticなので変更時には再起動が必要。 ログサンプル 1つ目がNeptune Workbench から実行したクエリ、もう一つがcurlからPostしたクエリ。 1584766979615, 10.0.1.18:34266, 10.0.3.215:8182, HTTP_POST, [unknown], [unknown], "HttpObjectAggregator$AggregatedFullHttpRequest(decodeResult: success, version: HTTP/1.1, content: CompositeByteBuf(ridx: 0, widx: 79, cap: 79, components=1)) POST /sparql HTTP/1.1 Host: neptestdb-cluster.cluster-xxxxxx.ap-northeast-1.neptune.amazonaws.com:8182 User-Agent: python-requests/2.20.0 Accept-Encoding: gzip, deflate Accept: */* Connection: keep-alive Content-Length: 79 Content-Type: application/x-www-form-urlencoded", query=SELECT+%2A%0AWHERE+%7B%0A++%3Fs+%3Fp+%3Fo+.%0A%7D%0ALIMIT+100%0AOFFSET+0+ 1584767048270, 10.0.1.123:56336, 10.0.3.215:8182, HTTP_POST, [unknown], [unknown], "HttpObjectAggregator$AggregatedFullHttpRequest(decodeResult: success, version: HTTP/1.1, content: CompositeByteBuf(ridx: 0, widx: 47, cap: 47, components=1)) POST /sparql HTTP/1.1 Host: neptestdb.xxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182 User-Agent: curl/7.61.1 Accept: */* Content-Length: 47 Content-Type: application/x-www-form-urlencoded", query=select ?s ?p ?o where {?s ?p ?o} limit 10 参考 Amazon Neptune クラスターで監査ログを使用する - Amazon Neptune https://docs.aws.amazon.com/ja_jp/neptune/latest/userguide/auditing.html --- ### 青空文庫のテキストデータをPostgreSQLに投入する date: 2020-04-04 url: https://zatoima.github.io/postgresql-aozora-date-insert.html tags: PostgreSQL このサイトを参考にさせて頂きました。SQL文作成のところが私の環境では動かなかったので別の方法に変えました。 青空文庫のデータでテキストマイニング(の準備) | ACALL BLOG https://blog.acall.jp/2019/11/aozorabunko-textmining/ 日本語の大容量のテキストデータが欲しかっただけで、綺麗に整形しておりませんのでご注意ください。 青空文庫のリポジトリからclone #sudo yum -y install git git clone --depth 1 https://github.com/aozorabunko/aozorabunko.git nkfのインストール wget https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/n/nkf-2.1.3-5.el7.x86_64.rpm sudo rpm -ivh nkf-2.1.3-5.el7.x86_64.rpm テキストファイルのマージ cd aozorabunko-master mdkir text find cards -name '*.zip' -exec cp {} text \; cd text unzip '*.zip' mkdir matome cp *.txt matome cd matome find . -name "*.txt" -exec cat {} >>matome.txt + nkf -w --overwrite matome.txt テキストファイルから実行用のSQLを作成 #テキストファイル内のシングルクォートを削除。シングルクォートがあると区切り文字を誤って判断してしまうため。 sed -e "s/'/ /g" matome.txt > matome1.sql sed "s/^/insert into aozoradata (data) values ('/g" matome1.sql > matome2.sql sed "s/$/');/g" matome2.sql > matome3.sql PostgreSQL側の準備 CREATE TABLE aozoradata( id serial not null, data text not null ); SQLファイルの実行 #時間が凄く掛かります。 psql -d postgres -U postgres -f matome3.sql 行数は3533485件となります。 postgres=# \d+ aozoradata; Table "public.aozoradata" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+---------+-----------+----------+----------------------------------------+----------+--------------+------------- id | integer | | not null | nextval('aozoradata_id_seq'::regclass) | plain | | data | text | | not null | | extended | | Indexes: "aozoradata_idx" gin (data gin_trgm_ops) postgres=# select count(*) from aozoradata; count --------- 3533485 (1 row) pgstattupleで確認してみるとこんな感じに。 postgres=# SELECT * FROM pgstattuple('aozoradata'); -[ RECORD 1 ]------+---------- table_len | 807690240 tuple_count | 3533485 tuple_len | 774167704 tuple_percent | 95.85 dead_tuple_count | 0 dead_tuple_len | 0 dead_tuple_percent | 0 free_space | 3066496 free_percent | 0.38 統計情報(pg_stats)から確認。avg_widthが190で意外と小さく感じた。 postgres=# select schemaname,tablename,attname,null_frac,avg_width,n_distinct,correlation from pg_stats where tablename='aozoradata'; -[ RECORD 1 ]------------ schemaname | public tablename | aozoradata attname | id null_frac | 0 avg_width | 4 n_distinct | -1 correlation | 0.999998 -[ RECORD 2 ]------------ schemaname | public tablename | aozoradata attname | data null_frac | 0 avg_width | 190 n_distinct | 114652 correlation | -0.00665814 青空文庫側の注釈や空行、ハイフン区切りが多く残っているので必要に応じて削除する必要があると思いますのでその場合は参考URLの中段以降をどうぞ。 青空文庫のデータでテキストマイニング(の準備) | ACALL BLOG https://blog.acall.jp/2019/11/aozorabunko-textmining/ --- ### Debug対応のPostgreSQL10をソースコードからビルドしてgdbを使用する date: 2020-04-03 url: https://zatoima.github.io/postgresql-gdb-postgresql-install.html tags: PostgreSQL PostgreSQL10.7を前提としています。 事前確認 GNU makeのバージョン 3.80以上であることを確認 make --version gccのインストール sudo yum -y install gcc readline-develパッケージ sudo yum -y install readline-devel zlib-develパッケージ sudo yum -y install zlib-devel OSユーザ作成 groupadd -g 1101 postgres useradd -u 1101 -g postgres -G postgres -d /var/lib/pgsql postgres passwd postgres 権限変更 chown -R postgres:postgres /var/lib/pgsql chmod -R 755 /var/lib/pgsql 環境変数に下記を追加 export PGDATA=/var/lib/pgsql/10/data PostgreSQLインストール ソースダウンロード&解凍 su - postgres wget https://ftp.postgresql.org/pub/source/v10.7/postgresql-10.7.tar.gz tar xvfz postgresql-10.7.tar.gz ビルド cd $HOME/postgresql-10.7 ./configure --enable-debug --prefix=/var/lib/pgsql/10 make All of PostgreSQL successfully made. Ready to install.が出力される。 インストール make install PostgreSQL installation complete.が出力される。 PostgreSQL初期化 DBの初期化 mkdir -p /var/lib/pgsql/10/data export PGDATA=/var/lib/pgsql/10/data whoami $HOME/10/bin/initdb --pgdata=$PGDATA $HOME/10/bin/pg_ctl start $HOME/10/bin/pg_ctl status 接続、バージョン確認 環境変数やPATHの設定を行い、接続を行う。 [postgres@postpub ~]$ psql psql (10.7) Type "help" for help. postgres=# select version(); version -------------------------------------------------------------------------------------------- ------------ PostgreSQL 10.7 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1 -6), 64-bit (1 row) gdb 本題のgdbを使ってみる。まずは接続中のPIDを確認する。 postgres=# select pg_backend_pid(); pg_backend_pid ---------------- 12072 (1 row) 当然、psコマンドからも確認が出来る。 [ec2-user@postpub ~]$ ps -ef | grep 12072 | grep -v grep postgres 12072 11888 0 03:42 ? 00:00:00 postgres: postgres postgres [local] idle gdbのインストール sudo yum -y install gdb [ec2-user@postpub ~]$ gdb -version GNU gdb (GDB) Red Hat Enterprise Linux 8.0.1-30.amzn2.0.3 Copyright (C) 2017 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word". プロセス番号をattachする。 gdb /var/lib/pgsql/10/bin/postgres 12072 [postgres@postpub bin]$ gdb /var/lib/pgsql/10/bin/postgres 12072 GNU gdb (GDB) Red Hat Enterprise Linux 8.0.1-30.amzn2.0.3 Copyright (C) 2017 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from /var/lib/pgsql/10/bin/postgres...done. Attaching to program: /var/lib/pgsql/10/bin/postgres, process 12072 Reading symbols from /lib64/libpthread.so.0...(no debugging symbols found)...done. [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Reading symbols from /lib64/librt.so.1...(no debugging symbols found)...done. Reading symbols from /lib64/libdl.so.2...(no debugging symbols found)...done. Reading symbols from /lib64/libm.so.6...(no debugging symbols found)...done. Reading symbols from /lib64/libc.so.6...(no debugging symbols found)...done. Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done. Reading symbols from /lib64/libnss_files.so.2...(no debugging symbols found)...done. 0x00007f0812262f90 in epoll_pwait () from /lib64/libc.so.6 Missing separate debuginfos, use: debuginfo-install glibc-2.26-34.amzn2.x86_64 (gdb) psql側で下記SQLを実行してみる。gdbで解析中は実行がstopする。(この言い方は正しくないかもしれない。) postgres=# select 1; bt (back trace) : バックトレース(関数呼出の履歴)を表示 (gdb) bt #0 0x00007f0812262f90 in epoll_pwait () from /lib64/libc.so.6 #1 0x00000000006c34ba in WaitEventSetWaitBlock (nevents=1, occurred_events=0x7ffd9a72e630, cur_timeout=-1, set=0x2483798) at latch.c:1048 #2 WaitEventSetWait (set=0x2483798, timeout=timeout@entry=-1, occurred_events=occurred_events@entry=0x7ffd9a72e630, nevents=nevents@entry=1, wait_event_info=wait_event_info@entry=100663296) at latch.c:1000 #3 0x0000000000603388 in secure_read (port=0x24aa550, ptr=0xc55e80 <PqRecvBuffer>, len=8192) at be-secure.c:169 #4 0x000000000060b888 in pq_recvbuf () at pqcomm.c:963 #5 0x000000000060c54b in pq_getbyte () at pqcomm.c:1006 #6 0x00000000006e16dd in SocketBackend (inBuf=0x7ffd9a72e770) at postgres.c:328 #7 ReadCommand (inBuf=0x7ffd9a72e770) at postgres.c:501 #8 PostgresMain (argc=<optimized out>, argv=argv@entry=0x24aff30, dbname=<optimized out>, username=<optimized out>) at postgres.c:4059 #9 0x0000000000479d43 in BackendRun (port=0x24aa550) at postmaster.c:4405 #10 BackendStartup (port=0x24aa550) at postmaster.c:4077 #11 ServerLoop () at postmaster.c:1755 #12 0x000000000068045c in PostmasterMain (argc=argc@entry=1, argv=argv@entry=0x2482be0) at postmaster.c:1363 #13 0x000000000047b309 in main (argc=1, argv=0x2482be0) at main.c:228 l (list) : ソースコードの確認 (gdb) list 47 const char *progname; 48 49 50 static void startup_hacks(const char *progname); 51 static void init_locale(const char *categoryname, int category, const char *locale); 52 static void help(const char *progname); 53 static void check_root(const char *progname); 54 55 56 /* (gdb) b (break 関数名) : プログラムを止めたい場所を指定 (gdb) l 64 * 'nil' if the constant qualification is not satisfied. 65 * ---------------------------------------------------------------- 66 */ 67 static TupleTableSlot * 68 ExecResult(PlanState *pstate) 69 { 70 ResultState *node = castNode(ResultState, pstate); 71 TupleTableSlot *outerTupleSlot; 72 PlanState *outerPlan; 73 ExprContext *econtext; (gdb) もう少し勉強してみます。 参考 第16章 ソースコードからインストール https://www.postgresql.jp/document/11/html/installation.html PostgreSQL の構造とソースツリー(3) | Let’s Postgres https://lets.postgresql.jp/node/167 目的別ガイド:内部解析編 | Let’s Postgres https://lets.postgresql.jp/node/10 --- ### Neptuneインスタンスのヘルスステータスをcurlコマンドで取得する方法 date: 2020-04-02 url: https://zatoima.github.io/aws-neptune-health-status.html tags: AWS, Neptune CloudWatchやマネージメントコンソール上からもインスタンスステータスは当然分かるが、curlコマンドでも確認可能。 [ec2-user@bastin ~]$ curl -G https://neptestdb.xxxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/status | jq { "status": "healthy", "startTime": "Sat Mar 21 03:06:07 UTC 2020", "dbEngineVersion": "1.0.2.1.R4", "role": "writer", "gremlin": { "version": "tinkerpop-3.4.1" }, "sparql": { "version": "sparql-1.1" }, "labMode": { "ObjectIndex": "disabled", "Streams": "enabled", "ReadWriteConflictDetection": "enabled" } } 項目 説明 status インスタンスの状態。正常な場合はhealthy。インスタンスがクラッシュまたは再起動から回復中で、最新のサーバーのシャットダウンからアクティブなトランザクションが実行されている場合、ステータスは “recovery” に設定 version Neptune エンジンバージョン。 startTime UTC時間でのインスタンスの起動時間 role writerインスタンスかReaderインスタンスか gremlin エンジンで使用されている現在の TinkerPop バージョンに設定 sparql エンジンで使用されている SPARQL の最新バージョン labMode ラボモード 設定が一覧表示 rollingBackTrxCount ロールバックされるトランザクションの数 rollingBackTrxEarliestStartTime ロールバックされる最も早いトランザクションの開始時刻 起動していない場合は、そもそもcurlコマンドがタイムアウト。 [ec2-user@bastin ~]$ curl -G https://neptestdb.xxxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/status curl: (7) Failed to connect to neptestdb.xxxxxxxx.ap-northeast-1.neptune.amazonaws.com port 8182: Connection timed out [ec2-user@bastin ~]$ --- ### PostgreSQLでfunctionの定義を確認する方法 date: 2020-03-31 url: https://zatoima.github.io/postgresql-function-describe-get.html tags: PostgreSQL チェック対象の関数(function) DROP FUNCTION IF EXISTS years_ago(INTEGER); CREATE OR REPLACE FUNCTION years_ago(INTEGER) RETURNS INTEGER AS $$ SELECT (extract(year from current_date)::INTEGER - first_appeared) FROM programming WHERE id = $1; $$ LANGUAGE sql; 方法1 : pg_proc の prosrcを使用 SELECT proname, prosrc FROM pg_proc WHERE proname = 'years_ago'; postgres=# SELECT proname, prosrc FROM pg_proc WHERE proname = 'years_ago'; proname | prosrc -----------+---------------------------------------------------------------------- years_ago | + | SELECT (extract(year from current_date)::INTEGER - first_appeared)+ | FROM programming + | WHERE id = $1; + | (1 row) 方法2 : pg_get_functiondefと組み合わせて使用する CREATE OR REPLACE FUNCTIONやその他の構文も合わせて出力してくれるので他環境に実行したい時とかに便利。 SELECT pg_get_functiondef((SELECT oid FROM pg_proc WHERE proname = 'years_ago')); postgres=# SELECT pg_get_functiondef((SELECT oid FROM pg_proc WHERE proname = 'years_ago')); pg_get_functiondef ---------------------------------------------------------------------- CREATE OR REPLACE FUNCTION public.years_ago(integer) + RETURNS integer + LANGUAGE sql + AS $function$ + SELECT (extract(year from current_date)::INTEGER - first_appeared)+ FROM programming + WHERE id = $1; + $function$ + (1 row) 方法3 : information_schema を使用する SELECT routine_definition FROM information_schema.routines WHERE routine_name = 'years_ago'; postgres=# SELECT routine_definition FROM information_schema.routines WHERE routine_name = 'years_ago'; routine_definition ---------------------------------------------------------------------- + SELECT (extract(year from current_date)::INTEGER - first_appeared)+ FROM programming + WHERE id = $1; + (1 row) --- ### PostgreSQLのpg_stat_statements参照時のについて date: 2020-03-29 url: https://zatoima.github.io/postgresql-pg-stat-statements-insuffient-priviledge/ tags: PostgreSQL いくつか気付きがあったのでメモ。superuserではない一般ユーザでpg_stat_statementsを参照した場合にinsufficient privilegeという出力があったことに気が付いた。 例えば**testAユーザで実行したクエリをtestAユーザで**pg_stat_statementsから確認しようとした場合、下記出力となる。 pgtest=> \c - testa You are now connected to database "pgtest" as user "testa". pgtest=> \x Expanded display is off. pgtest=> SELECT query FROM pg_stat_statements WHERE dbid=16392 ORDER BY total_time DESC LIMIT 20; query --------------------------------------------------------------------------------------------------------------- create table userA.pgtesttbl(id numeric primary key, name varchar) CREATE SCHEMA userA AUTHORIZATION userA SELECT query, calls, total_time, rows FROM pg_stat_statements WHERE dbid=$1 ORDER BY total_time DESC LIMIT $2 insert into userA.pgtesttbl values($1,$2) select oid,datname from pg_database (5 rows) 一方、**別ユーザ(testB)**からこのクエリを取得しようとすると、insufficient privilegeと出力される。 pgtest=> \c - testb You are now connected to database "pgtest" as user "testb". pgtest=> SELECT query FROM pg_stat_statements WHERE dbid=16392 ORDER BY total_time DESC LIMIT 20; query | calls | total_time | rows --------------------------+-------+------------+------ <insufficient privilege> | 1 | 5.340486 | 0 <insufficient privilege> | 1 | 0.45077 | 0 <insufficient privilege> | 3 | 0.288345 | 10 <insufficient privilege> | 1 | 0.106162 | 1 <insufficient privilege> | 1 | 0.016645 | 4 Oracleと違い、PostgreSQLはシステムカタログ(稼働統計ビュー含む)に対する細かい権限制御が出来ない一方、こういった実行したユーザ以外にはクエリを見せないような実装になっていることを知った。 F.30. pg_stat_statements https://www.postgresql.jp/document/10/html/pgstatstatements.html セキュリティ上の理由から、スーパーユーザとpg_read_all_statsロールのメンバだけが、他のユーザによって実行されたSQLテキストや問い合わせのqueryidを見ることができます。 上記のマニュアルにも特定のロールがないと他のユーザによって実行されたSQLテキストは見れないよ、と記載がある。pg_monitorにpg_read_all_statsも内包されているのでスーパーユーザかpg_read_all_statsかpg_monitorさえあれば全てのテキストを見れる。監視用のユーザを作成する際には注意。 ロールについてはこちらに詳しく書いてあったので合わせてどうぞ。 監視用デフォルトロール - Qiita https://qiita.com/nuko_yokohama/items/6debdd3291c8f27d1da8 --- ### Amazon NeptuneのRDFデータをExportする date: 2020-03-27 url: https://zatoima.github.io/aws-neptune-export-rdf-data.html tags: AWS, Neptune, RDF, SPARQL はじめに awslabsに用意されているNeptune用のツールを使用してRDFデータをTurtleへエクスポートしてみる。 amazon-neptune-tools/neptune-export at master · awslabs/amazon-neptune-tools https://github.com/awslabs/amazon-neptune-tools/tree/master/neptune-export 詳細な使用方法についてreadme.mdをご参照ください。 amazon-neptune-tools/readme.md at master · awslabs/amazon-neptune-tools https://github.com/awslabs/amazon-neptune-tools/blob/master/neptune-export/readme.md awslabs/amazon-neptune-tools https://github.com/awslabs/amazon-neptune-tools/blob/master/neptune-export/docs/export-rdf.md 注意点 Exporting an RDF Graph については At present neptune-export supports exporting an RDF dataset to Turtle with a single-threaded long-running query.と記載があります。データ容量とか関わってきますが、シングルスレッドで動作する関係上長時間のエクスポートとなる可能性があります。実行時間や実行対象のインスタンスの負荷状況については留意する必要があると思います。クローンで別インスタンスを立てる、Read Replica側を使うなどの考慮は必要かと。 環境確認 実際に実行してみます。検証のためにデータを最小限にしています。ロードされているデータは下記の通りです。 SELECT * WHERE { ?s ?p ?o . } LIMIT 100 OFFSET 0 実行 outputのディレクトリの作成 mkdir -p /home/ec2-user/output awslabsからneptune-exportツールのダウンロード #sudo yum -y install git git clone https://github.com/awslabs/amazon-neptune-tools.git Mavenのインストール sudo wget http://repos.fedorapeople.org/repos/dchen/apache-maven/epel-apache-maven.repo -O /etc/yum.repos.d/epel-apache-maven.repo sudo sed -i s/\$releasever/6/g /etc/yum.repos.d/epel-apache-maven.repo sudo yum install -y apache-maven mvn --version jarファイルのbuildを実行する cd /home/ec2-user/amazon-neptune-tools/neptune-export mvn clean install targetディレクトリ配下にneptune-export.jarがビルドされる [ec2-user@bastin neptune-export]$ ls -l target total 62712 drwxrwxr-x 4 ec2-user ec2-user 28 Feb 24 05:13 classes drwxrwxr-x 3 ec2-user ec2-user 25 Feb 24 05:13 generated-sources drwxrwxr-x 3 ec2-user ec2-user 30 Feb 24 05:13 generated-test-sources drwxrwxr-x 2 ec2-user ec2-user 28 Feb 24 05:13 maven-archiver drwxrwxr-x 3 ec2-user ec2-user 35 Feb 24 05:13 maven-status -rw-rw-r-- 1 ec2-user ec2-user 202719 Feb 24 05:13 neptune-export-1.0-SNAPSHOT.jar -rw-rw-r-- 1 ec2-user ec2-user 64006996 Feb 24 05:14 neptune-export.jar drwxrwxr-x 2 ec2-user ec2-user 4096 Feb 24 05:13 surefire-reports drwxrwxr-x 3 ec2-user ec2-user 17 Feb 24 05:13 test-classes [ec2-user@bastin neptune-export]$ neptune-export.shの実行 cd /home/ec2-user/amazon-neptune-tools/neptune-export sh ./bin/neptune-export.sh export-rdf -e neptestdb.xxxxxxxxx.ap-northeast-1.neptune.amazonaws.com -d /home/ec2-user/output ※bin配下ではなく、一つ上のneptune-exportで実行する必要がある。neptune-export.jarを検索した上で変数に格納しているため。 jar=$(find . -name neptune-export.jar) java -jar ${jar} "$@" ※neptuneのインスタンス名を指定しますが、「https」は抜いてください。怒られます。 Completed export-rdf in 0 seconds An error occurred while exporting from Neptune: java.lang.RuntimeException: org.eclipse.rdf4j.query.QueryEvaluationException: https: Name or service not known at com.amazonaws.services.neptune.rdf.NeptuneSparqlClient.executeQuery(NeptuneSparqlClient.java:166) at com.amazonaws.services.neptune.rdf.io.ExportRdfGraphJob.execute(ExportRdfGraphJob.java:31) 実行後はoutputディレクトリ配下にttlが出力されています。トリプルは一致していますね。 cd /home/ec2-user/output/1584768727668/statements [ec2-user@bastin statements]$ cat statements-0.ttl <http://aws.amazon.com/neptune/a> <http://xmlns.com/foaf/0.1/interest> <http://dbpedia.org/resource/Satomi_Ishihara> . <http://aws.amazon.com/neptune/b> <http://xmlns.com/foaf/0.1/interest> <http://dbpedia.org/resource/Haruka_Ayase> . <http://aws.amazon.com/neptune/c> <http://xmlns.com/foaf/0.1/interest> <http://dbpedia.org/resource/Honda_Tsubasa> . <http://aws.amazon.com/neptune/d> <http://xmlns.com/foaf/0.1/interest> <http://dbpedia.org/resource/Haruka_Ayase> . 出力可能なフォーマット「turtle(デフォルト)」「nquads」「json(neptuneStreamsJson)」となります。 json(neptuneStreamsJson)の場合はこうなりました。 [ec2-user@bastin neptune-export]$ sh ./bin/neptune-export.sh export-rdf --format neptuneStreamsJson -e neptestdb.xxxxxxxxx.ap-northeast-1.neptune.amazonaws.com -d /home/ec2-user/output Creating statement files /home/ec2-user/output/1584769323164 [ec2-user@bastin statements]$ cat statements-0.json | jq { "eventId": { "commitNum": -1, "opNum": 0 }, "data": { "stmt": "<http://aws.amazon.com/neptune/a> <http://xmlns.com/foaf/0.1/interest> <http://dbpedia.org/resource/Satomi_Ishihara> ." }, "op": "ADD" } { "eventId": { "commitNum": -1, "opNum": 0 }, "data": { "stmt": "<http://aws.amazon.com/neptune/b> <http://xmlns.com/foaf/0.1/interest> <http://dbpedia.org/resource/Haruka_Ayase> ." }, "op": "ADD" } { "eventId": { "commitNum": -1, "opNum": 0 }, "data": { "stmt": "<http://aws.amazon.com/neptune/c> <http://xmlns.com/foaf/0.1/interest> <http://dbpedia.org/resource/Honda_Tsubasa> ." }, "op": "ADD" } { "eventId": { "commitNum": -1, "opNum": 0 }, "data": { "stmt": "<http://aws.amazon.com/neptune/d> <http://xmlns.com/foaf/0.1/interest> <http://dbpedia.org/resource/Haruka_Ayase> ." }, "op": "ADD" } 余談 最初はエラーが発生して正常完了出来なかったのですが、Stack Overflowに投稿したら修正してくれました。助かりました。 amazon web services - regarding about export of neptune data - Stack Overflow https://stackoverflow.com/questions/60429428/regarding-about-export-of-neptune-data --- ### RDS/Auroraのログファイルをawscliから取得・確認する date: 2020-03-25 url: https://zatoima.github.io/aws-aurora-rds-log-file-get.html tags: AWS, Aurora, RDS, PostgreSQL マネージメントコンソールから確認するのが面倒な時にCLIから実行するのを想定しています。 事前準備 jqコマンドを使って整形するので事前にインストールする sudo yum -y install jq ログ・ファイルの取得方法 aws rds describe-db-instances | jq '.DBInstances[].DBInstanceIdentifier' aws rds describe-db-log-files --db-instance-identifier aurorapostgresqlv1-instance-1 aws rds download-db-log-file-portion --db-instance-identifier aurorapostgresqlv1-instance-1 --log-file-name "error/postgres.log" --output text 実行例 取得対象のインスタンス名を取得 [ec2-user@bastin ~]$ aws rds describe-db-instances | jq '.DBInstances[].DBInstanceIdentifier' "aurorapostgresqlv1-instance-1" [ec2-user@bastin ~]$ 出力されているログ・ファイルの取得 最新のファイルかどうかはLastWrittenから確認可能。 [ec2-user@bastin ~]$ aws rds describe-db-log-files --db-instance-identifier aurorapostgresqlv1-instance-1 { "DescribeDBLogFiles": [ { "LastWritten": 1582951862000, "LogFileName": "error/postgres.log", "Size": 1380 }, { "LastWritten": 1582951868000, "LogFileName": "error/postgresql.log.2020-02-29-0451", "Size": 891 }, { "LastWritten": 1582952400000, "LogFileName": "error/postgresql.log.2020-02-29-0500", "Size": 0 }, { "LastWritten": 1582956000000, "LogFileName": "error/postgresql.log.2020-02-29-0600", "Size": 0 } ] } ログ・ファイルを出力 [ec2-user@bastin ~]$ aws rds download-db-log-file-portion --db-instance-identifier aurorapostgresqlv1-instance-1 --log-file-name "error/postgres.log" --output text 2020-02-29 04:51:01.093 GMT [5665] LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2020-02-29 04:51:01 UTC::@:[5665]:WARNING: unrecognized configuration parameter "rds.custom_dns_resolution" 2020-02-29 04:51:01 UTC::@:[5665]:WARNING: unrecognized configuration parameter "rds.enable_plan_management" 2020-02-29 04:51:01 UTC::@:[5665]:LOG: database system is shut down Postgres Shared Memory Value: 11132993536 bytes 2020-02-29 04:51:02.647 GMT [5783] LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf" 2020-02-29 04:51:02 UTC::@:[5783]:WARNING: unrecognized configuration parameter "rds.custom_dns_resolution" 2020-02-29 04:51:02 UTC::@:[5783]:WARNING: unrecognized configuration parameter "rds.enable_plan_management" 2020-02-29 04:51:02 UTC::@:[5783]:LOG: listening on IPv4 address "0.0.0.0", port 5432 2020-02-29 04:51:02 UTC::@:[5783]:LOG: listening on IPv6 address "::", port 5432 2020-02-29 04:51:02 UTC::@:[5783]:LOG: listening on Unix socket "/tmp/.s.PGSQL.5432" 2020-02-29 04:51:02 UTC::@:[5783]:LOG: could not write pg_stat_statement file "pg_stat_tmp/pgss_query_texts.stat": No such file or directory 2020-02-29 04:51:02 UTC::@:[5783]:LOG: redirecting log output to logging collector process 2020-02-29 04:51:02 UTC::@:[5783]:HINT: Future log output will appear in directory "/rdsdbdata/log/error". --- ### tweepyを使用したtwitter apiの操作 date: 2020-03-24 url: https://zatoima.github.io/twitter-api-tweepy-python-operation.html tags: python, tweepy, Twitter API 前提条件 Twitter APIの使用申請を行い下記のkeyやtokenを取得していること Consumer_key Consumer_secret Access_token Access_secret 参考:Twitter API 登録 (アカウント申請方法) から承認されるまでの手順まとめ ※2019年8月時点の情報 - Qiita https://qiita.com/kngsym2018/items/2524d21455aac111cdee サンプル 実際に試してみる。tweepyはtwitter apiを簡単に使うためのwrapperなので短いコードでtwitterの基本的操作をすることが出来る。 tweepyのimportと接続認証 取得したkeyとtokenの設定、及びtwitterオブジェクトの生成、認証周りを行う。 import tweepy Consumer_key = 'xxxxxxxxxxxxxxx' Consumer_secret = 'xxxxxxxxxxxxxxxxxxx' Access_token = 'xxxxxxxxxxxxxxxxxxxxxxxx' Access_secret = 'xxxxxxxxxxxxxxxxxxx' # Twitterオブジェクトの生成 auth=tweepy.OAuthHandler(Consumer_key,Consumer_secret) auth.set_access_token(Access_token,Access_secret) api=tweepy.API(auth) 特定ユーザのタイムラインを表示する status=api.user_timeline(id='zatoima1')[0] print(status.user.name) print(status.text) 結果 zato RT @motikiro2: パソコンの排気口を塞ぐツボツボとネコネコ https://t.co/fbfq7GDLbK statusオブジェクトには下記の情報が格納されるためこちらを参照することで各種操作を自動化することが可能。 オブジェクト 格納情報 status.text ツイート status.id ツイート固有のID status.in_reply_to_status_id リプライ先のツイートID status.retweet_count リツイート数 status.favorite_count いいねの数 status.user.name ユーザー名 status.user.screen_name スクリーンネーム(@zatoima1) status.user.friends_count フォロー数 status.user.followers_count フォロワー数 status.user.description 自己紹介 その他の格納情報についてはこちらも参照。 tweepyのstatusオブジェクトに格納される情報一覧 | my opinion is my own https://zatoima.github.io/twitter-api-tweepy-status-list.html 特定ツイートの自動いいね、自動リツイート、自動フォロー 次にこのオブジェクトを使用してbot作成に役に立ちそうな例を記載する。例えば下記のpythonのコードではAWSという文言を含むツイートを20件検索している。検索に引っかかったツイートからユーザ情報やツイート情報を取得して"status"オブジェクトに格納。statusオブジェクトに格納されているツイートやユーザに対して、「①いいね」、「②リツイート」、「③フォロー」を実施している。 この例では検索して引っかかったキーワードに対しての操作だが、Twitterに関わる操作であればほとんど出来るみたいなので、Twitter botや特定キーワードに対して瞬時にいいねをするアカウントはこの辺を自動化しているためなんだな、と実感。 q_list=["#AWS"] count=20 for q in q_list: print("Now:QUERY-->>{}".format(q)) search_results=api.search(q=q,count=count) for status in search_results: tweet_id=status.id user_id=status.user.name try: api.create_favorite(tweet_id) api.retweet(tweet_id) api.create_friendship(user_id) except: pass print("Done:QUERY-->>{}".format(q)) ※いいね、リツイート、フォローには回数制限があるので注意が必要。凍結リスクがあります。ご注意ください。 開発者契約およびポリシー ‒ Twitter開発者 https://developer.twitter.com/ja/developer-terms/agreement-and-policy --- ### PostgreSQLのpg_settingsビューにはunit列があり単位が見れる date: 2020-03-23 url: https://zatoima.github.io/postgresql-pg_setting-unit.html tags: PostgreSQL pg_settingsビューにはunit列があってここでパラメータの単位がわかる。便利。 postgres=# select name,setting,unit from pg_settings where name like '%wal%'; name | setting | unit ------------------------------+-----------+------ max_wal_senders | 10 | max_wal_size | 1024 | MB min_wal_size | 80 | MB wal_block_size | 8192 | wal_buffers | 512 | 8kB wal_compression | off | wal_consistency_checking | | wal_keep_segments | 0 | wal_level | replica | wal_log_hints | off | wal_receiver_status_interval | 10 | s wal_receiver_timeout | 60000 | ms wal_retrieve_retry_interval | 5000 | ms wal_segment_size | 2048 | 8kB wal_sender_timeout | 60000 | ms wal_sync_method | fdatasync | wal_writer_delay | 200 | ms wal_writer_flush_after | 128 | 8kB (18 rows) [改訂新版]内部構造から学ぶPostgreSQL 設計・運用計画の鉄則:書籍案内|技術評論社 https://gihyo.jp/book/2018/978-4-297-10089-6 --- ### OSS-DB Gold | オープンソースデータベース技術者認定資格 Gold 認定エンジニアになりました date: 2020-03-22 url: https://zatoima.github.io/postgresql-ossdb-gold-exam.html tags: PostgreSQL はじめに OSS-DB Gold Ver.2.0に合格しました。 この試験は下記の知識とスキルを証明してくれるみたいです。オープンソースデータベースと主語が大きいですが、身につくのはPostgreSQLオンリーだと思います。 RDBMSとSQLに関する知識を有する。 オープンソースデータベースに関する深い知識を有する。 オープンソースを利用して大規模なデータベースの運用管理ができる。 オープンソースを利用して大規模なデータベースの開発を行う事ができる。 PostgreSQLなどのOSS-DBの内部構造を熟知している。 PostgreSQLなどのOSS-DBの利用方法やデータベースの状態を検証してパフォーマンスチューニングをすることができる。 PostgreSQLなどのOSS-DBの利用方法やデータベースの状態を検証してトラブルシューティングをすることができる。 なお、OSS-DB Goldは「ITSSのキャリアフレームワークと認定試験・資格との関係」ではレベル3に位置付けられています。Oracle Master Goldと同等です。 資格取得のメリット https://oss-db.jp/merit 試験の概要などはこちらのページご参照ください。 OSS-DB Gold https://oss-db.jp/outline/gold 試験の範囲 結構他の資格試験にはないレベルで詳細に試験範囲が書かれています。 下記は大項目レベルで抜粋しています。 運用管理(30%) データベースサーバ構築 【重要度:2】 運用管理用コマンド全般 【重要度:4】 データベースの構造 【重要度:2】 ホット・スタンバイ運用 【重要度:1】 性能監視(30%) アクセス統計情報 【重要度:3】 テーブル / カラム統計情報 【重要度:2】 クエリ実行計画 【重要度:3】 その他の性能監視 【重要度:1】 パフォーマンス・チューニング(20%) 性能に関係するパラメータ 【重要度:4】 チューニングの実施 【重要度:2】 障害対応(20%) 起こりうる障害のパターン 【重要度:3】 破損クラスタ復旧 【重要度:2】 ホット・スタンバイ復旧 【重要度:1】 「データベースサーバ構築」では「テーブル・インデックス容量見積もり」や「通信経路暗号化(SSL)」が必要な知識とあります。「track_functions」や「pg_tblspc」、「pg_xact」などのパラメータ、システムカタログ、ディレクトリも試験範囲ということがわかります。 OSS-DB Gold Ver.2.0に特化した教科書というのは存在しない(※古い教科書はあります)ので、この試験範囲に相当するマニュアルと実機を使い勉強するのが一番かなーと思っています。 使用教材 ①LPI-Japan OSS-DB Gold 認定教材 PostgreSQL 高度技術者育成テキスト ②公式サイトのサンプル問題 ③OSS-DB Gold セミナー資料 ④マニュアル、実機検証 LPI-Japan OSS-DB Gold 認定教材 PostgreSQL 高度技術者育成テキスト 公式テキストを買いました。OSS-DB Gold Ver.2.0に対応したテキストではないのですが、唯一手頃な値段で変えるテキストがあったので購入しました。ただ、こちらは2014年頃に発売、対応バージョンも9.xです。本書と公式ドキュメントとを突き合わせて実機で練習を重ねるのが前提です。Oracle Masterの白本や黒本を期待して買うと痛い目を見ると思います。 ただ、一部古いですが、試験範囲に対して網羅的にまとまってあるので有効です。(※もちろん試験バージョンが変わっているので一部抜けがあります。)問題集が付いているのが特に良い!実際の試験に対して難しく感じましたが、、、 公式サイトのサンプル問題 サンプル問題/例題解説 https://oss-db.jp/sample OSS-DB Gold セミナー資料 参考資料ダウンロード https://oss-db.jp/measures/download マニュアル、実機検証、市販本 高度技術者育成テキスト、サンプル問題、セミナー資料に一通り目を通したあとにあとは上記の試験範囲と見比べつつ、地道にマニュアルと実機検証を行いました。以前にこの本を読んでたいたのですが、読み直しました。 所感 勉強期間は2週間~3週間くらいでした。OSS-DB Silverは2019年12月末に取得しています。 Goldに合格出来て思うことは、詳細に記載してある試験範囲に沿ってマニュアルを読んで、公式のサンプル問題を解くのが一番良いなって感じました。PostgreSQL 高度技術者育成テキストは範囲的には大きく被っていますが、記載内容が荒いのでこの本だけでは太刀打ちできません。内容的にも古いので、PostgreSQL 10や11あたりのマニュアルを読むことをお奨めします。 重箱の隅をつつくような問題も確かにあってマニュアル読んでても実機を触ってても覚えていないというのはあるのでその部分については、「サンプル問題」や「PostgreSQL 高度技術者育成テキスト」の問題部分でレベル感を掴んだほうが良いと思います。例えばpg_statsの各列の意味まで出題されるのですが、一つ一つ抑えていないので焦りました。 とはいえ、私はOracleの資格、知識は持っているので、その知識と比べつつ知識を埋めていく形でやりました。最短で受かることを目的とせずに実機触ることを目的として楽しくやれたのでそこまで苦ではなかったです。Oracleよりも機能がシンプルである分、勉強する範囲が少なくてすみました。マニュアルも時間が空いている時に読めば数日で一周出来ます。 試験問題数も30問と少ないので有効性に関しては個人的には疑問なのですが、マニュアルを一通り眺めて実機を触ることでPostgreSQLの入門は出来たかな、という印象です。普段はAuroraやRDSを触ることが多いのですが、生のPostgreSQLの知識やスキルも必要だとは思うので引き続き勉強していきます。 --- ### ソースコードからPostgreSQL11.7をインストールする date: 2020-03-21 url: https://zatoima.github.io/postgresql-11.7-install-source-code.html tags: PostgreSQL PostgreSQL11.7を前提としています。PostgreSQLはyumでもソースからビルドするパターンでも簡単。 事前確認 GNU makeのバージョン 3.80以上であることを確認 make --version gccのインストール sudo yum -y install gcc readline-develパッケージ sudo yum -y install readline-devel zlib-develパッケージ sudo yum -y install zlib-devel OSユーザ作成 groupadd -g 1101 postgres useradd -u 1101 -g postgres -G postgres -d /home/postgres postgres passwd postgres PostgreSQLインストール(postgresユーザで実施) ソースダウンロード&解凍 wget https://ftp.postgresql.org/pub/source/v11.7/postgresql-11.7.tar.gz tar xvfz postgresql-11.7.tar.gz ソースコードに手を入れる場合はこのタイミングで修正 cd ./postgresql-11.7/contrib/pg_trgm vi ./trgm.h #KEEPONLYALNUM を コメントアウトする ビルド&インストール cd $HOME/postgresql-11.7 ./configure --prefix=$HOME/pgsql/11 make make install PostgreSQL初期化 $PGDATA を作成 mkdir -p /home/postgres/pgsql/11/data DBの初期化 sudo su - postgres whoami export PGDATA=/home/postgres/pgsql/11/data /home/postgres/pgsql/11/bin/initdb --pgdata=$PGDATA /home/postgres/pgsql/11/bin/pg_ctl start --pgdata=$PGDATA /home/postgres/pgsql/11/bin/pg_ctl status --pgdata=$PGDATA 接続、バージョン確認 [postgres@post11db bin]$ ./psql psql (11.7) Type "help" for help. postgres=# postgres=# select version(); version -------------------------------------------------------------------------------------------------------- PostgreSQL 11.7 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-6), 64-bit (1 row) 参考 第16章 ソースコードからインストール https://www.postgresql.jp/document/11/html/installation.html --- ### OSS-DB Gold対策(運用管理 - データベースサーバ構築) date: 2020-03-20 url: https://zatoima.github.io/postgresql-pgcrypt-encrypt.html tags: PostgreSQL はじめに OSS-DB Gold(オープンソースデータベース技術者認定試験)を目指し勉強しようと思ったが、ここ5年以内にリリースされた本がないので試験概要を基にマニュアルや実機、Webの他の先駆者の情報を基に勉強していくことにした。 OSS-DBは他の試験に比べて出題範囲が明確で、ここには記載していませんが「重要な用語、コマンド、パラメータ」の記載がある。すべての試験範囲を確認したい場合は、下記の試験概要を見て頂ければ。 OSS-DB Gold https://oss-db.jp/outline/gold 今回は運用管理のデータベースサーバ構築についてまとめてみる。大した内容はなく、ただのメモです。 試験範囲 運用管理(30%) データベースサーバ構築 【重要度:2】 運用管理用コマンド全般 【重要度:4】 データベースの構造 【重要度:2】 ホット・スタンバイ運用 【重要度:1】 性能監視(30%) アクセス統計情報 【重要度:3】 テーブル / カラム統計情報 【重要度:2】 クエリ実行計画 【重要度:3】 その他の性能監視 【重要度:1】 パフォーマンス・チューニング(20%) 性能に関係するパラメータ 【重要度:4】 チューニングの実施 【重要度:2】 障害対応(20%) 起こりうる障害のパターン 【重要度:3】 破損クラスタ復旧 【重要度:2】 ホット・スタンバイ復旧 【重要度:1】 運用管理 - データベースサーバ構築 この試験範囲の説明、主要な知識範囲、重要な用語、コマンド、パラメータは次の通り。 説明: サーバ構築における容量見積もり、およびデータベースセキュリティに関する知識を問う 主要な知識範囲: テーブル・インデックス容量見積もり セキュリティ 通信経路暗号化(SSL) データ暗号化 クライアント認証 監査ログ データ型のサイズ ユーザ・データベース単位のパラメータ設定 重要な用語、コマンド、パラメータなど: チェックサム pg_xact pg_multixact pg_notify pg_serial pg_snapshots pg_stat_tmp pg_subtrans pg_tblspc pg_twophase ssl pg_stat_ssl pgcrypto ALTER ROLE ALTER DATABASE initdb -data-checksums (-k) log_statement track_functions track_activities 試験に向けた整理 テーブル・インデックス容量見積もり テーブルの内部構造(ページ)は下記の通りとなる。 項目 説明 ページヘッダ 長さは24バイト。空き領域ポインタを含む、ページについての一般情報が含まれる ラインポインタ 実際のアイテムを指すアイテム識別子の配列。1アイテムにつき4バイト。 FreeSpace 割り当てられていない空間。ラインポインタはこの領域の先頭から、新規のアイテム(タプル)は末尾から割り当てられる タプル 実際のデータ(行データ) 特別な空間 インデックスアクセスメソッド特有のデータなので通常のテーブルでは空となる。 下記のt1テーブルを例に計算する。 postgres=# select tablename, attname, avg_width from pg_stats where tablename = 't1'; tablename | attname | avg_width -----------+---------+----------- t1 | a | 4 t1 | b | 2 t1 | c | 6 t1 | d | 8 (4 rows) 上記の結果から1タプル(1行)で必要とされるbyte数は(4+2+6+8)で20bytesとなる。1タプルごとにラインポインタ の4バイトが必要になるため、この例の場合、1タプルあたり24bytesが必要になる。 1ページに入るタプル数 = (8192 - PageHeaderData ) / ( 1タプルのサイズ + ItemIdData ) = (8192 - 24) / ( 20 + 4 ) = 8168 / 24 = 340.33 したがって、1ページ入るタプル数は約340となる。例えばタプル数が10000の場合、必要なblock数は 240,000byteとなる。ページ数の場合は30000ページとなる。 今回はFILLFACTORの考慮はしていないが、90%だとすると下記計算となる。 1ページに入るタプル数 = (8192 - PageHeaderData ) / ( 1タプルのサイズ + ItemIdData ) = (8192 - 24 - 819 ) / ( 20 + 4 ) = 8168 / 24 = 306 なお、インデックスの場合のページ構造は下記となる。 セキュリティ 通信経路暗号化(SSL) データ暗号化 クライアント認証 監査ログ データ型のサイズ 文字型 PostgreSQLデータ型 最大長 概要 VARCHAR(n) 1GB 長さn文字の可変長文字列 CHAR(n) 1GB 長さn文字の固定長文字データ。指定した長さより短CHAR,CLOBい値を挿入したときは、残りは空白で埋められる TEXT 1GB 長さ指定なしの可変長文字列 数値型 PostgreSQLデータ型 最大長 概要 INTEGER 4バイト 整数型。数値の範囲と保存のサイズ、性能のバランスNUMBERが良い SMALLINT 2バイト 範囲の狭い整数型 BIGINT 8バイト 範囲の広い整数型 NUMERIC 1000桁 正と負の固定小数点数。小数点より右側の桁数と全体の桁数を指定できる REAL 4バイト 単精度の浮動小数点数 DOUBLE PRECISION 8バイト 倍精度の浮動小数点数 日付型 PostgreSQLデータ型 最大長 概要 DATE 4バイト 1日単位で日付のみを表すデータ TIMESTAMP 8バイト 日付と時刻の両方を表すデータ バイナリ型 PostgreSQLデータ型 最大長 概要 bytea 1GB 可変長のバイナリデータ ラージオブジェクト 2GB データベース内に格納される チェックサム(initdb -data-checksums (-k)) データチェックサムは、PostgreSQLのデータベースクラスタ初期化時に、有効にするかどうかを指定。-kオプションを付ける。 initdb -D $PGDATA -k pg_xact pg_multixact pg_notify pg_serial pg_snapshots pg_stat_tmp pg_subtrans pg_tblspc pg_twophase 66.1. データベースファイルのレイアウト https://www.postgresql.jp/document/10/html/storage-file-layout.html 項目 説明 PG_VERSION PostgreSQLの主バージョン番号を保有するファイル base データベースごとのサブディレクトリを保有するサブディレクトリ current_logfiles ログ収集機構が現在書き込んでいるログファイルを記録するファイル global pg_databaseのようなクラスタで共有するテーブルを保有するサブディレクトリ pg_commit_ts トランザクションのコミット時刻のデータを保有するサブディレクトリ pg_dynshmem 動的共有メモリサブシステムで使われるファイルを保有するサブディレクトリ pg_logical 論理デコードのための状態データを保有するサブディレクトリ pg_multixact マルチトランザクションの状態のデータを保有するサブディレクトリ(共有行ロックで使用されます) pg_notify LISTEN/NOTIFY状態データを保有するサブディレクトリ pg_replslot レプリケーションスロットデータを保有するサブディレクトリ pg_serial コミットされたシリアライザブルトランザクションに関する情報を保有するサブディレクトリ pg_snapshots エクスポートされたスナップショットを保有するサブディレクトリ pg_stat 統計サブシステム用の永続ファイルを保有するサブディレクトリ pg_stat_tmp 統計サブシステム用の一時ファイルを保有するサブディレクトリ pg_subtrans サブトランザクションの状態のデータを保有するサブディレクトリ pg_tblspc テーブル空間へのシンボリックリンクを保有するサブディレクトリ pg_twophase プリペアドトランザクション用の状態ファイルを保有するサブディレクトリ pg_wal WAL(ログ先行書き込み)ファイルを保有するサブディレクトリ pg_xact トランザクションのコミット状態のデータを保有するサブディレクトリ postgresql.auto.conf ALTER SYSTEMにより設定された設定パラメータを格納するのに使われるファイル postmaster.opts 最後にサーバを起動した時のコマンドラインオプションを記録するファイル postmaster.pid 現在のpostmasterプロセスID(PID)、クラスタのデータディレクトリパス、postmaster起動時のタイムスタンプ、ポート番号、Unixドメインソケットのディレクトリパス(Windowsでは空)、有効な監視アドレスの一番目(IPアドレスまたは*、TCPを監視していない場合は空)および共有メモリのセグメントIDを記録するロックファイル(サーバが停止した後は存在しません) ssl pg_stat_ssl pg_stat_sslビューは、バックエンドプロセスおよびWAL送信プロセスごとに1行を保持し、接続上でのSSLの使用に関する統計情報を示します。 28.2. 統計情報コレクタ https://www.postgresql.jp/document/10/html/monitoring-stats.html#PG-STAT-SSL-VIEW pgcrypto インストール pgbench=# CREATE EXTENSION pgcrypto; CREATE EXTENSION pgbench=# \dx List of installed extensions Name | Version | Schema | Description -------------+---------+------------+------------------------------ pgcrypto | 1.3 | public | cryptographic functions pgstattuple | 1.5 | public | show tuple-level statistics plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language (3 rows) pgbench=# \dx+ Objects in extension "pgcrypto" Object description ------------------------------------------------------- function armor(bytea) function armor(bytea,text[],text[]) function crypt(text,text) function dearmor(text) function decrypt(bytea,bytea,text) function decrypt_iv(bytea,bytea,bytea,text) function digest(bytea,text) function digest(text,text) function encrypt(bytea,bytea,text) function encrypt_iv(bytea,bytea,bytea,text) function gen_random_bytes(integer) function gen_random_uuid() function gen_salt(text) function gen_salt(text,integer) function hmac(bytea,bytea,text) function hmac(text,text,text) function pgp_armor_headers(text) function pgp_key_id(bytea) function pgp_pub_decrypt(bytea,bytea) function pgp_pub_decrypt_bytea(bytea,bytea) function pgp_pub_decrypt_bytea(bytea,bytea,text) function pgp_pub_decrypt_bytea(bytea,bytea,text,text) function pgp_pub_decrypt(bytea,bytea,text) function pgp_pub_decrypt(bytea,bytea,text,text) function pgp_pub_encrypt_bytea(bytea,bytea) function pgp_pub_encrypt_bytea(bytea,bytea,text) function pgp_pub_encrypt(text,bytea) function pgp_pub_encrypt(text,bytea,text) function pgp_sym_decrypt_bytea(bytea,text) function pgp_sym_decrypt_bytea(bytea,text,text) function pgp_sym_decrypt(bytea,text) function pgp_sym_decrypt(bytea,text,text) function pgp_sym_encrypt_bytea(bytea,text) function pgp_sym_encrypt_bytea(bytea,text,text) function pgp_sym_encrypt(text,text) function pgp_sym_encrypt(text,text,text) (36 rows) pgcryptはcontribモジュールの一つなので必要に応じてcontribのインストールも実施が必要。 sudo yum -y install postgresql10-devel postgresql10-contrib 関数の使用方法 pgcryptには上記で確認したように多くの関数が用意されている。一般的な関数を試す。 digest 汎用ハッシュ関数 digest(data text, type text) returns bytea digest(data bytea, type text) returns bytea md5、sha1、sha224、sha256、sha384、およびsha512が標準の暗号化アルゴリズムとして用意されている。 使用例 pgbench=# select digest('aaaa','sha256'); digest -------------------------------------------------------------------- \x61be55a8e2f6b4e172338bddf184d6dbee29c98853e0a0485ecee7f27b9af0b4 hmac keyをキーとしたdataのハッシュ化MACを計算。MACはMessage Authentication Code。 hmac(data text, key text, type text) returns bytea hmac(data bytea, key bytea, type text) returns bytea typeはdigestと同じくmd5、sha1、sha224、sha256、sha384、およびsha512が標準の暗号化アルゴリズム。 keyが一致しなければ同じハッシュ値にならない。 使用例 pgbench=# select hmac('aaaa','key1','sha256'); hmac -------------------------------------------------------------------- \xbb9d9016b60ef5ebe72e859d5a5f630c62fff00571361998267a3f6d7c12e482 (1 row) pgbench=# select hmac('aaaa','key2','sha256'); hmac -------------------------------------------------------------------- \xdca517b3144dc65219660ecd0e2d1c2e19f70b6122f5289e82f093f87e2daaa0 (1 row) crypt() パスワードハッシュ化関数 crypt(password text, salt text) returns text saltはgen_salt()を使用して生成する必要がある。des、xdes、md5、bfがアルゴリズムとして使用可能。 使用方法 pgbench=# select crypt('CRYPTPASSWORD', gen_salt('md5')); crypt ------------------------------------ $1$UniwWec.$NnpXvamtau8zEXjyoVHU./ (1 row) log_statement エラー報告とログ取得 https://www.postgresql.jp/document/9.3/html/runtime-config-logging.html どのSQL文をログに記録するかを制御します。 有効な値は、none(off)、ddl、mod、およびall(全てのメッセージ)です。 ddlは、CREATE、ALTER、およびDROP文といった、データ定義文を全てログに記録します。 track_functions 関数の呼び出し数と費やされた時間の追跡を有効にします。 デフォルトは、統計情報追跡機能を無効にするnoneです。 スーパーユーザのみがこの設定を変更できます。 track_activities 実行時統計情報 https://www.postgresql.jp/document/9.2/html/runtime-config-statistics.html 各セッションで実行中のコマンドに関する情報とそのコマンドの実行開始時刻の収集を有効にします。 このパラメータはデフォルトで有効です。 有効な場合であっても、すべてのユーザがこの情報を見ることができず、スーパーユーザと報告されたセッションの所有者のみから可視である点に注意してください。 このためセキュリティ上の危険性はありません。 スーパーユーザのみがこの設定を変更することができます。 --- ### PostgreSQLの全文検索エンジンであるpg_trgmを使ってみる date: 2020-03-17 url: https://zatoima.github.io/postgresql-pg_trgm-about.html tags: PostgreSQL PostgreSQLでIndexを利用した「中間一致検索」を行うケース。通常のB-Treeインデックスの場合、中間一致検索時は使用できない。pg_trgmというPostgreSQLの全文検索エンジンを使用することによって中間一致検索を手軽に行うことが出来る。pg_bigmやPGroongaもあるが、今回はcontribに含まれているpg_trgmを試してみる。 バージョン postgres=# select version(); version ---------------------------------------------------------------------------------------------------------- PostgreSQL 10.11 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39), 64-bit pg_trgmの有効化 postgres=# CREATE EXTENSION pg_trgm; CREATE EXTENSION postgres=# \dx List of installed extensions Name | Version | Schema | Description ---------+---------+------------+------------------------------------------------------------------- pg_trgm | 1.3 | public | text similarity measurement and index searching based on trigrams plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language (2 rows) テストデータを適当に作る(1億件のテキストデータ) CREATE TABLE t1 AS SELECT to_char(num,'FM0000000000000000') textdata FROM generate_series(1,10000000) num ; 検索対象のテキストデータを挿入 insert into t1 values('test1test2test3'); insert into t1 values('メロスは激怒した。必ず、かの 邪智暴虐 ( じゃちぼうぎゃく ) の王を除かなければならぬと決意した。'); ここまでで1億2件のデータがテーブルに格納されている。 select count(*) from t1; postgres=# select count(*) from t1; count ----------- 100000002 (1 row) “test2"が含まれる中間検索 explain analyze select * from t1 where textdata like '%test2%'; explain analyze結果 Execution time: 10061.160 msほど時間が掛かっている。約10秒。テーブルのフルスキャンとなるので遅い。 postgres=# explain analyze select * from t1 where textdata like '%test2%'; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- Gather (cost=1000.00..1159776.58 rows=10000 width=17) (actual time=10059.633..10061.097 rows=1 loops=1) Workers Planned: 2 Workers Launched: 2 -> Parallel Seq Scan on t1 (cost=0.00..1157776.58 rows=4167 width=17) (actual time=10053.097..10053.098 rows=0 loops=3) Filter: (textdata ~~ '%test2%'::text) Rows Removed by Filter: 33333334 Planning time: 0.938 ms Execution time: 10061.160 ms (8 rows) ““邪智暴虐"“が含まれる中間検索 explain analyze select * from t1 where textdata like '%邪智暴虐%'; explain analyze結果 Execution time: 9982.465 msほど時間が掛かっている。こちらも同じく約10秒。 postgres=# explain analyze select * from t1 where textdata like '%邪智暴虐%'; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------- Gather (cost=1000.00..1159776.58 rows=10000 width=17) (actual time=9982.347..9982.403 rows=1 loops=1) Workers Planned: 2 Workers Launched: 2 -> Parallel Seq Scan on t1 (cost=0.00..1157776.58 rows=4167 width=17) (actual time=9977.282..9977.282 rows=0 loops=3) Filter: (textdata ~~ '%邪智暴虐%'::text) Rows Removed by Filter: 33333334 Planning time: 0.052 ms Execution time: 9982.465 ms (8 rows) 全文検索用のインデックスの作成 create index pg_trgm_idx on t1 USING gin(textdata gin_trgm_ops); 作成完了まで約300秒掛かっている。 [2020-03-16 21:27:36 JST]postgres postgres 4539[53] LOG: statement: create index pg_trgm_idx on t1 USING gin(textdata gin_trgm_ops); [2020-03-16 21:32:39 JST]postgres postgres 4539[54] LOG: duration: 303535.309 ms テーブルのサイズは約5217.8MB=約5GB程度。インデックスのサイズは約1,461MB=約1GB。全文検索用のインデックスの場合はテーブルサイズ<インデックスサイズとなると思ってた。テスト用データが原因かもしれない。 SELECT objectname, TO_CHAR(pg_relation_size(objectname::regclass),'999,999,999,999') AS bytes FROM ( SELECT tablename AS objectname FROM pg_tables WHERE schemaname = 'public' UNION SELECT indexname AS objectname FROM pg_indexes WHERE schemaname = 'public' ) AS objectlist ORDER BY bytes DESC; objectname | bytes -------------+------------------ t1 | 5,217,837,056 pg_trgm_idx | 1,461,542,912 (2 rows) test2が含まれる中間検索 explain analyze select * from t1 where textdata like '%test2%'; explain analyze結果 Execution time: 10061.160 msほど時間が掛かっていた検索が0.090 msで完了。 postgres=# explain analyze select * from t1 where textdata like '%test2%'; QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- Bitmap Heap Scan on t1 (cost=285.50..36386.84 rows=10000 width=17) (actual time=0.021..0.022 rows=1 loops=1) Recheck Cond: (textdata ~~ '%test2%'::text) Heap Blocks: exact=1 -> Bitmap Index Scan on pg_trgm_idx (cost=0.00..283.00 rows=10000 width=0) (actual time=0.016..0.016 rows=1 loops=1) Index Cond: (textdata ~~ '%test2%'::text) Planning time: 1.148 ms Execution time: 0.090 ms (7 rows) 邪智暴虐が含まれる中間検索 explain analyze select * from t1 where textdata like '%邪智暴虐%'; explain analyze結果 Execution time: 9982.465 msほど時間が掛かっていた検索が0.044 msで完了。 postgres=# explain analyze select * from t1 where textdata like '%邪智暴虐%'; QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- Bitmap Heap Scan on t1 (cost=217.50..36318.84 rows=10000 width=17) (actual time=0.022..0.022 rows=1 loops=1) Recheck Cond: (textdata ~~ '%邪智暴虐%'::text) Heap Blocks: exact=1 -> Bitmap Index Scan on pg_trgm_idx (cost=0.00..215.00 rows=10000 width=0) (actual time=0.017..0.017 rows=1 loops=1) Index Cond: (textdata ~~ '%邪智暴虐%'::text) Planning time: 0.107 ms Execution time: 0.044 ms (7 rows) なお、トライグラム(tri-gram)の性質上、致し方ないが、2文字以下の検索は激遅になるので注意。 postgres=# explain analyze select * from t1 where textdata like '%邪智%'; QUERY PLAN ------------------------------------------------------------------------------------------------------------------ Bitmap Heap Scan on t1 (cost=758005.50..794106.84 rows=10000 width=17) (actual time=169524.760..169524.761 rows=1 loops=1) Recheck Cond: (textdata ~~ '%邪智%'::text) Rows Removed by Index Recheck: 100000001 Heap Blocks: exact=636943 -> Bitmap Index Scan on pg_trgm_idx (cost=0.00..758003.00 rows=10000 width=0) (actual time=26370.882..26370.882 rows=100000002 loops=1) Index Cond: (textdata ~~ '%邪智%'::text) Planning time: 0.261 ms Execution time: 169524.849 ms (8 rows) postgres=# Recheck Cond について 下記の記事がすごくわかりやすかった。 Bitmap Index Scan の後の Bitmap Heap Scan でRecheck処理が行われることの解説 - ぱと隊長日誌 https://taityo-diary.hatenablog.jp/entry/2018/07/07/071928 postgresql - What does “Recheck Cond” in Explain result mean? - Stack Overflow https://stackoverflow.com/questions/50959814/what-does-recheck-cond-in-explain-result-mean/50961326#50961326 追記 データを青空文庫のテキストデータに変更してみたらこうなった。想定通り、テーブルサイズよりインデックスサイズの方が大きくなった。 postgres=# SELECT * FROM pgstattuple('aozoradata'); -[ RECORD 1 ]------+---------- table_len | 807690240 tuple_count | 3533485 tuple_len | 774167704 tuple_percent | 95.85 dead_tuple_count | 0 dead_tuple_len | 0 dead_tuple_percent | 0 free_space | 3066496 free_percent | 0.38 postgres=# \d aozoradata Table "public.aozoradata" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+---------------------------------------- id | integer | | not null | nextval('aozoradata_id_seq'::regclass) data | text | | not null | postgres=# SELECT postgres-# objectname, postgres-# TO_CHAR(pg_relation_size(objectname::regclass),'999,999,999,999') AS bytes postgres-# FROM postgres-# ( postgres(# SELECT postgres(# tablename AS objectname postgres(# FROM postgres(# pg_tables postgres(# WHERE postgres(# schemaname = 'public' postgres(# UNION postgres(# SELECT postgres(# indexname AS objectname postgres(# FROM postgres(# pg_indexes postgres(# WHERE postgres(# schemaname = 'public' postgres(# ) AS objectlist postgres-# ORDER BY postgres-# bytes DESC; objectname | bytes ----------------+------------------ aozoradata | 807,690,240 aozoradata_idx | 1,156,775,936 (2 rows) --- ### PostgreSQLの自動Vacuumの実行タイミングと関連するパラメータ date: 2020-03-16 url: https://zatoima.github.io/postgresql-auto-vacuum-parameter-timing.html tags: PostgreSQL Auto Vacuumの概要 デフォルトでonになっているAuto Vacuum。Vacuumと同時にAnalyzeも実施してくれます。マニュアル的にはAuto Vacuumが推奨です。 24.1. 定常的なバキューム作業 https://www.postgresql.jp/document/10/html/routine-vacuuming.html Auto Vacuumの実行タイミング バキュームの実行タイミングは UPDATE+DELETE回数 = 閾値 < autovacuum_vacuum_threshold(デフォルト 50)+ autovacuum_vacuum_scale_factor(デフォルト0.2) × pg_class.reltuples 一方、Analyzeの実行タイミングは UPDATE+DELETE+INSERT回数 = 閾値 < autovacuum_analyze_threshold(デフォルト 50)+ autovacuum_analyze_scale_factor(デフォルト0.1) × pg_class.reltuplesとなる。 ※pg_class.reltuplesはテーブル内の行数。 VACUUM、ANALYZE、CREATE INDEXなどの一部のDDLコマンドで更新される。 Auto Vacuumのパラメータについて パラメータ 分類 デフォルト パラメータ説明 autovacuum VACUUM on 自動バキュームを行うかどうか log_autovaccum_min_duration VACUUM -1 指定した時間(ミリ秒)以上に処理を行った場合にログを出力する。デフォルトでは無効 autovacuum_max_workers VACUUM 3 自動バキュームの同時実行ワーカーの最大数 autovaccum_naptime VACUUM 1min 自動バキュームの必要性を確認する期間 autovacuum_vacuum_threshold VACUUM 50 VACUUMを起動するために必要な、更新もしくは削除されたタプルの最小数 autovacuum_vacuum_scale_factor VACUUM 0.2 VACUUMを起動するか否かを決定するときに、autovacuum_vacuum_thresholdに足し算するテーブル容量の割合を指定 autovacuum_analyze_threshold ANALYZE 50 ANALYZEを起動するために必要な、更新もしくは削除されたタプルの最小数 autovacuum_analyze_scale_factor ANALYZE 0.1 ANALYZEを起動するか否かを決定するときに、autovacuum_vacuum_thresholdに足し算するテーブル容量の割合を指定 実行履歴の確認方法 \x SELECT schemaname, relname, last_vacuum, last_autovacuum, last_analyze, last_autoanalyze, vacuum_count, autovacuum_count, autoanalyze_count FROM pg_stat_user_tables; 実行結果 -[ RECORD 1 ]-----+------------------------------ schemaname | public relname | pgbench_tellers last_vacuum | 2020-02-29 07:29:38.682063+00 last_autovacuum | 2020-02-29 05:40:58.708216+00 last_analyze | 2020-02-29 07:29:38.682594+00 last_autoanalyze | 2020-02-29 05:40:58.708747+00 vacuum_count | 8 autovacuum_count | 28 autoanalyze_count | 27 -[ RECORD 2 ]-----+------------------------------ schemaname | public relname | pgbench_history last_vacuum | 2020-02-29 07:29:38.73807+00 last_autovacuum | last_analyze | 2020-02-29 07:29:38.747484+00 last_autoanalyze | 2020-02-29 05:40:58.744441+00 vacuum_count | 3 autovacuum_count | 0 autoanalyze_count | 20 -[ RECORD 3 ]-----+------------------------------ schemaname | public relname | pgbench_branches last_vacuum | 2020-02-29 07:29:38.683765+00 last_autovacuum | 2020-02-29 05:40:58.721649+00 last_analyze | 2020-02-29 07:29:38.683963+00 last_autoanalyze | 2020-02-29 05:40:58.72242+00 vacuum_count | 8 autovacuum_count | 28 autoanalyze_count | 27 -[ RECORD 4 ]-----+------------------------------ schemaname | public relname | pgbench_accounts last_vacuum | 2020-02-29 07:29:38.69804+00 last_autovacuum | last_analyze | 2020-02-29 07:29:38.734999+00 last_autoanalyze | 2020-02-27 13:24:59.247779+00 vacuum_count | 3 autovacuum_count | 0 autoanalyze_count | 25 参考 19.10. 自動Vacuum作業 https://www.postgresql.jp/document/10/html/runtime-config-autovacuum.html --- ### PostgreSQLのHugePagesの設定 date: 2020-03-15 url: https://zatoima.github.io/postgresql-hugepages-setting.html tags: PostgreSQL メモリはpagesとよばれるブロック単位で管理されており、x86 アーキテクチャのデフォルトページサイズは 4096 バイト。HugePage は、それよりも大きなページサイズ (デフォルトで 2 MB) で管理する機能であるためshared_buffersの値が大きい場合に、huge pagesを使用するとオーバーヘッドが減少するというのが概要。 事前確認 カーネルでHugePagesがサポートされているかどうかを確認。 ※CONFIG_HUGETLBFSおよびCONFIG_HUGETLB_PAGE構成オプションを使用してLinuxカーネルを構築 grep Huge /proc/meminfo PostgreSQLの場合は、下記マニュアルに従いhugepages数を見積もる。Oracleみたくhugepages_settings.sh的なものはない。 18.4. カーネルリソースの管理 https://www.postgresql.jp/document/10/html/kernel-resources.html#LINUX-HUGE-PAGES 必要なHugePages数の見積もり方法 [postgres@postdb ~]$ head -1 $PGDATA/postmaster.pid 5811 [postgres@postdb ~]# grep ^VmPeak /proc/5811/status VmPeak: 5565496 kB [postgres@postdb ~]# grep ^Hugepagesize /proc/meminfo Hugepagesize: 2048 kB 上記より、5565496kb/2048kb = 2,717.52734375‬となり、2718のhugepagesが必要と判断できる。 OS側の設定 sysctl -w vm.nr_hugepages=2718 再起動後にもこの数値を使用するように/etc/sysctl.confに設定して永続化する。 cat "vm.nr_hugepages=2718" >> /etc/sysctl.conf hugepagesの割当の確認 grep Huge /proc/meminfo [postgres@postdb ~]$ grep Huge /proc/meminfo AnonHugePages: 0 kB ShmemHugePages: 0 kB HugePages_Total: 2718 HugePages_Free: 2638 HugePages_Rsvd: 2511 HugePages_Surp: 0 Hugepagesize: 2048 kB [postgres@postdb ~]$ DB側にてパラメータセット(postgresql.conf) huge_pages=on 念のためにパラメータ確認 [postgres@postdb data]$ psql psql (10.11) Type "help" for help. postgres=# postgres=# show huge_pages; huge_pages ------------ on (1 row) 参考 18.4. カーネルリソースの管理 https://www.postgresql.jp/document/10/html/kernel-resources.html#LINUX-HUGE-PAGES --- ### PostgreSQLのcheckpoint_completion_targetについてメモ date: 2020-03-13 url: https://zatoima.github.io/postgresql-about-checkpoint_completion_target.html tags: PostgreSQL PostgreSQLのcheckpoint_completion_targetについてメモ。 19.5. ログ先行書き込み(WAL) https://www.postgresql.jp/document/10/html/runtime-config-wal.html#GUC-CHECKPOINT-TIMEOUT checkpoint_completion_target チェックポイントの完了目標をチェックポイント間の総時間の割合として指定します。 デフォルトは0.5です。 このパラメータはpostgresql.confファイル、または、サーバのコマンドラインでのみ設定可能です。 postgres=# show checkpoint_completion_target; checkpoint_completion_target ------------------------------ 0.5 (1 row) 一方、checkpoint_timeoutというパラメータがありデフォルトでは5分が設定されている。自動的WALチェックポイント間の最大間隔を秒単位で指定できるパラメータである。 このcheckpoint_completion_targetはcheckpoint_timeoutで設定された"割合"の時間を使ってcheckpointをしていくという動きをして負荷を分散する。あくまで目安程度となるらしい。 postgres=# show checkpoint_timeout; checkpoint_timeout -------------------- 5min (1 row) デフォルトの通り、checkpoint_timeoutが5分でcheckpoint_completion_targetが0.5の場合は約2.5分(あくまで目安)掛けてダーティーページをディスクに書き込んでいくという処理となる。 つまり、checkpoint_completion_targetを低くした場合はcheckpointでダーティーページをディクスに書き込む際の負荷が高くなることが予想され、checkpoint_completion_targetを高くした場合(=時間を掛ける)は、クラッシュリカバリ時に処理をするWALファイルが増える。 更新が多くcheckpointの負荷が気になる場合はcheckpoint_completion_targetをデフォルトの0.5から「0.6~0.9」に引き上げることを考慮。 --- ### PostgreSQLの実行中のSQLをキャンセルする date: 2020-03-12 url: https://zatoima.github.io/postgresql-sql-statement-cancell.html tags: PostgreSQL 長時間掛かるクエリ実行 直積結合して件数カウント。 select count(*) from t1,t2,t3,t4,t5; 実行中のSQLの確認 postgres=# select pid,query_start,state,query from pg_stat_activity order by query_start asc limit 5; pid | query_start | state | query ------+-------------------------------+--------+--------------------------------------------------------------------------------------- 2567 | 2020-03-03 03:39:22.744191+00 | active | select count(*) from t1,t2,t3,t4,t5; 2863 | 2020-03-03 03:44:25.423124+00 | active | select pid,query_start,state,query from pg_stat_activity order by query_start asc limit 5; 実行中のSQLのキャンセル 下記の関数でキャンセル可能。pg_cancel_backendはSIGINT。pg_terminate_backendはSIGTERMのシグナルをサーバ側に送る模様。 9.26. システム管理関数 https://www.postgresql.jp/document/10/html/functions-admin.html#FUNCTIONS-ADMIN-SIGNAL-TABLE 名前 戻り型 説明 pg_cancel_backend(pid int) boolean バックエンドの現在の問い合わせを取り消す。 関数を呼ぶユーザが取り消す対象のバックエンドのロールのメンバーであるとき、あるいはpg_signal_backendの権限を与えられているときも実行できます。 ただし、スーパーユーザのバックエンドはスーパーユーザのみが取り消せます。 pg_terminate_backend(pid int) boolean バックエンドを終了する。 関数を呼ぶユーザが終了対象のバックエンドのロールのメンバーであるとき、あるいはpg_signal_backendの権限を与えられているときも実行できます。 ただし、スーパーユーザのバックエンドはスーパーユーザのみが終了できます。 pg_cancel_backend関数 バックエンドの現在の問い合わせを取り消す。実行した場合、SQL実行はキャンセルするが、接続したまま。 select pg_cancel_backend(2567); postgres=# select pg_cancel_backend(2567); pg_cancel_backend ------------------- t (1 row) -- terminal postgres=# select count(*) from t1,t2,t3,t4,t5; ERROR: canceling statement due to user request -- log [2020-03-03 03:52:20 UTC]postgres postgres 2567[27] ERROR: canceling statement due to user request [2020-03-03 03:52:20 UTC]postgres postgres 2567[28] STATEMENT: select count(*) from t1,t2,t3,t4,t5; pg_terminate_backend関数 pg_terminate_backendは接続自体を切断され、その後に再接続がされる。 select pg_terminate_backend(2567); postgres=# select pg_terminate_backend(2567); pg_terminate_backend ---------------------- t (1 row) -- terminal postgres=# select count(*) from t1,t2,t3,t4,t5; FATAL: terminating connection due to administrator command server closed the connection unexpectedly This probably means the server terminated abnormally before or while processing the request. The connection to the server was lost. Attempting reset: Succeeded. -- log [2020-03-03 03:54:14 UTC]postgres postgres 2567[29] FATAL: terminating connection due to administrator command [2020-03-03 03:54:14 UTC]postgres postgres 2567[30] STATEMENT: select count(*) from t1,t2,t3,t4,t5; [2020-03-03 03:54:14 UTC]postgres postgres 2567[31] LOG: disconnection: session time: 0:33:20.877 user=postgres database=postgres host=[local] [2020-03-03 03:54:14 UTC][unknown] [unknown] 2918[1] LOG: connection received: host=[local] [2020-03-03 03:54:14 UTC]postgres postgres 2918[2] LOG: connection authorized: user=postgres database=postgres --- ### シグナル(TERM/INT/HUP)によるPostgresプロセスへの影響 date: 2020-03-11 url: https://zatoima.github.io/postgresql-signal-process-term-int-hup.html tags: PostgreSQL 表題の通り、シグナル(TERM/INT/HUP)によるpostgresプロセスへの影響を確認してみます。 PostgreSQLのシャットダウンモードについて まず前提となるシャットダウン時のモード。 shutdown mode 説明 スマートシャットダウンモード 新しい接続を禁止しますが、既に存在するセッションは通常通り動作。既存セッションが通常に終了するまではシャットダウンしない。 高速シャットダウンモード サーバは新しい接続を禁止し全ての存在するサーバプロセスにSIGTERMを送り、この結果サーバプロセスは現在のトランザクションをアボートし、即座に終了する 即時シャットダウン 全ての子プロセスに SIGQUITを送り、即座に終了。次回起動時にWALを使用してリカバリをする必要がある。 次にシグナルを送った場合(killした場合)の挙動を確認してみる。 SIGINTの場合 [postgres@postdb ~]$ ps -ef | grep "/usr/pgsql-10/bin/postgres" | grep -v grep postgres 5632 1 0 03:00 pts/3 00:00:00 /usr/pgsql-10/bin/postgres [postgres@postdb ~]$ kill -SIGINT 5632 log出力 高速シャットダウンモードとなる [2020-03-10 12:02:28 JST] 5632[7] LOG: received fast shutdown request [2020-03-10 12:02:28 JST] 5632[8] LOG: aborting any active transactions [2020-03-10 12:02:28 JST] 5632[9] LOG: worker process: logical replication launcher (PID 5641) exited with exit code 1 [2020-03-10 12:02:28 JST] 5635[1] LOG: shutting down [2020-03-10 12:02:28 JST] 5635[2] LOG: checkpoint starting: shutdown immediate [2020-03-10 12:02:28 JST] 5635[3] LOG: checkpoint complete: wrote 1 buffers (0.0%); 0 WAL file(s) added, 10 removed, 0 recycled; write=0.015 s, sync=0.000 s, total=0.046 s; sync files=1, longest=0.000 s, average=0.000 s; distance=16384 kB, estimate=16384 kB [2020-03-10 12:02:28 JST] 5632[10] LOG: database system is shut down SIGTERMの場合 [postgres@postdb ~]$ ps -ef | grep "/usr/pgsql-10/bin/postgres" | grep -v grep postgres 5678 1 9 03:06 pts/3 00:00:00 /usr/pgsql-10/bin/postgres [postgres@postdb ~]$ kill -SIGTERM 5678 log出力 スマートシャットダウンモード [2020-03-10 12:06:56 JST] 5678[7] LOG: received smart shutdown request [2020-03-10 12:06:56 JST] 5678[8] LOG: worker process: logical replication launcher (PID 5687) exited with exit code 1 [2020-03-10 12:06:56 JST] 5681[1] LOG: shutting down [2020-03-10 12:06:56 JST] 5681[2] LOG: checkpoint starting: shutdown immediate [2020-03-10 12:06:56 JST] 5681[3] LOG: checkpoint complete: wrote 0 buffers (0.0%); 0 WAL file(s) added, 1 removed, 0 recycled; write=0.015 s, sync=0.000 s, total=0.024 s; sync files=0, longest=0.000 s, average=0.000 s; distance=16384 kB, estimate=16384 kB [2020-03-10 12:06:56 JST] 5678[9] LOG: database system is shut down SIGHUPの場合 [postgres@postdb ~]$ ps -ef | grep "/usr/pgsql-10/bin/postgres" | grep -v grep postgres 5695 1 3 03:08 pts/3 00:00:00 /usr/pgsql-10/bin/postgres [postgres@postdb ~]$ kill -SIGHUP 5695 log出力 SIGHUPの場合はパラメータファイルの再読み込み [2020-03-10 12:08:33 JST] 5695[7] LOG: received SIGHUP, reloading configuration files SIGQUITの場合 [postgres@postdb ~]$ ps -ef | grep "/usr/pgsql-10/bin/postgres" | grep -v grep postgres 5695 1 0 03:08 pts/3 00:00:00 /usr/pgsql-10/bin/postgres [postgres@postdb ~]$ kill -SIGQUIT 5695 log出力 即時シャットダウンとなる [2020-03-10 12:09:40 JST] 5695[8] LOG: received immediate shutdown request [2020-03-10 12:09:40 JST] 5701[1] WARNING: terminating connection because of crash of another server process [2020-03-10 12:09:40 JST] 5701[2] DETAIL: The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory. [2020-03-10 12:09:40 JST] 5701[3] HINT: In a moment you should be able to reconnect to the database and repeat your command. [2020-03-10 12:09:40 JST] 5695[9] LOG: archiver process (PID 5702) exited with exit code 1 [2020-03-10 12:09:40 JST] 5695[10] LOG: database system is shut down 即時シャットダウンとなるので、次回起動時にはredo startsの適用が始まる。 [2020-03-10 12:10:06 JST] 5725[1] LOG: database system was interrupted; last known up at 2020-03-10 12:08:20 JST [2020-03-10 12:10:06 JST] 5725[2] LOG: database system was not properly shut down; automatic recovery in progress [2020-03-10 12:10:06 JST] 5725[3] LOG: redo starts at 3/71000098 [2020-03-10 12:10:06 JST] 5725[4] LOG: invalid record length at 3/710000D0: wanted 24, got 0 [2020-03-10 12:10:06 JST] 5725[5] LOG: redo done at 3/71000098 [2020-03-10 12:10:06 JST] 5725[6] LOG: checkpoint starting: end-of-recovery immediate [2020-03-10 12:10:06 JST] 5725[7] LOG: checkpoint complete: wrote 0 buffers (0.0%); 0 WAL file(s) added, 1 removed, 0 recycled; write=0.013 s, sync=0.000 s, total=0.019 s; sync files=0, longest=0.000 s, average=0.000 s; distance=0 kB, estimate=0 kB [2020-03-10 12:10:06 JST] 5723[6] LOG: database system is ready to accept connections --- ### LODデータの作成方法の参考リンク date: 2020-03-10 url: https://zatoima.github.io/loddata-how-to-create-link.html tags: Graph, Neptune, LOD, RDF Linked Open Data(リンクト・オープン・データ、略名: LOD)の公開方法についてまとめているリンク集。ExcelデータやRDBMSに格納されている構造データ、CSVデータをどのようにLOD化するのかイメージ付いていなかったが、これを見ればなんとなく出来る感じがする。 --- ### EC2(Amazon Linux)にMavenをインストール date: 2020-03-09 url: https://zatoima.github.io/aws-ec2-maven-install.html tags: AWS, EC2, Maven github上のjavaソースのbuildにmavenが必要だったので、インストールメモ。 コマンド sudo wget http://repos.fedorapeople.org/repos/dchen/apache-maven/epel-apache-maven.repo -O /etc/yum.repos.d/epel-apache-maven.repo sudo sed -i s/\$releasever/6/g /etc/yum.repos.d/epel-apache-maven.repo sudo yum install -y apache-maven mvn --version 実行例 [ec2-user@bastin]$ sudo wget http://repos.fedorapeople.org/repos/dchen/apache-maven/epel-apache-maven.repo -O /etc/yum.repos.d/epel-apache-maven.repo --2020-02-24 04:47:19-- http://repos.fedorapeople.org/repos/dchen/apache-maven/epel-apache-maven.repo Resolving repos.fedorapeople.org (repos.fedorapeople.org)... 152.19.134.199, 2610:28:3090:3001:5054:ff:fea7:9474 Connecting to repos.fedorapeople.org (repos.fedorapeople.org)|152.19.134.199|:80... connected. HTTP request sent, awaiting response... 302 Found Location: https://repos.fedorapeople.org/repos/dchen/apache-maven/epel-apache-maven.repo [following] --2020-02-24 04:47:20-- https://repos.fedorapeople.org/repos/dchen/apache-maven/epel-apache-maven.repo Connecting to repos.fedorapeople.org (repos.fedorapeople.org)|152.19.134.199|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 445 Saving to: ‘/etc/yum.repos.d/epel-apache-maven.repo’ 100%[==================================================================================================================================================>] 445 --.-K/s in 0s 2020-02-24 04:47:20 (24.6 MB/s) - ‘/etc/yum.repos.d/epel-apache-maven.repo’ saved [445/445] [ec2-user@bastin]$ sudo sed -i s/\$releasever/6/g /etc/yum.repos.d/epel-apache-maven.repo [ec2-user@bastin]$ sudo yum install -y apache-maven Loaded plugins: langpacks, priorities, update-motd epel-apache-maven | 3.3 kB 00:00:00 epel-apache-maven/x86_64/primary_db | 5.0 kB 00:00:01 Resolving Dependencies --> Running transaction check ---> Package apache-maven.noarch 0:3.5.2-1.el6 will be installed --> Processing Dependency: java-1.7.0-openjdk-devel for package: apache-maven-3.5.2-1.el6.noarch --> Running transaction check ---> Package java-1.7.0-openjdk-devel.x86_64 1:1.7.0.241-2.6.20.0.amzn2.0.2 will be installed --> Processing Dependency: java-1.7.0-openjdk = 1:1.7.0.241-2.6.20.0.amzn2.0.2 for package: 1:java-1.7.0-openjdk-devel-1.7.0.241-2.6.20.0.amzn2.0.2.x86_64 --> Running transaction check ---> Package java-1.7.0-openjdk.x86_64 1:1.7.0.241-2.6.20.0.amzn2.0.2 will be installed --> Processing Dependency: java-1.7.0-openjdk-headless = 1:1.7.0.241-2.6.20.0.amzn2.0.2 for package: 1:java-1.7.0-openjdk-1.7.0.241-2.6.20.0.amzn2.0.2.x86_64 --> Processing Dependency: libpulse.so.0(PULSE_0)(64bit) for package: 1:java-1.7.0-openjdk-1.7.0.241-2.6.20.0.amzn2.0.2.x86_64 --> Processing Dependency: libpulse.so.0()(64bit) for package: 1:java-1.7.0-openjdk-1.7.0.241-2.6.20.0.amzn2.0.2.x86_64 --> Running transaction check ---> Package java-1.7.0-openjdk-headless.x86_64 1:1.7.0.241-2.6.20.0.amzn2.0.2 will be installed --> Processing Dependency: libgconf-2.so.4()(64bit) for package: 1:java-1.7.0-openjdk-headless-1.7.0.241-2.6.20.0.amzn2.0.2.x86_64 ---> Package pulseaudio-libs.x86_64 0:10.0-3.amzn2.0.2 will be installed --> Processing Dependency: libsndfile.so.1(libsndfile.so.1.0)(64bit) for package: pulseaudio-libs-10.0-3.amzn2.0.2.x86_64 --> Processing Dependency: libsndfile.so.1()(64bit) for package: pulseaudio-libs-10.0-3.amzn2.0.2.x86_64 --> Processing Dependency: libasyncns.so.0()(64bit) for package: pulseaudio-libs-10.0-3.amzn2.0.2.x86_64 --> Running transaction check ---> Package GConf2.x86_64 0:3.2.6-8.amzn2.0.2 will be installed --> Processing Dependency: libpolkit-gobject-1.so.0()(64bit) for package: GConf2-3.2.6-8.amzn2.0.2.x86_64 --> Processing Dependency: libdbus-glib-1.so.2()(64bit) for package: GConf2-3.2.6-8.amzn2.0.2.x86_64 ---> Package libasyncns.x86_64 0:0.8-7.amzn2.0.2 will be installed ---> Package libsndfile.x86_64 0:1.0.25-10.amzn2.0.2 will be installed --> Processing Dependency: libvorbisenc.so.2()(64bit) for package: libsndfile-1.0.25-10.amzn2.0.2.x86_64 --> Processing Dependency: libvorbis.so.0()(64bit) for package: libsndfile-1.0.25-10.amzn2.0.2.x86_64 --> Processing Dependency: libogg.so.0()(64bit) for package: libsndfile-1.0.25-10.amzn2.0.2.x86_64 --> Processing Dependency: libgsm.so.1()(64bit) for package: libsndfile-1.0.25-10.amzn2.0.2.x86_64 --> Processing Dependency: libFLAC.so.8()(64bit) for package: libsndfile-1.0.25-10.amzn2.0.2.x86_64 --> Running transaction check ---> Package dbus-glib.x86_64 0:0.100-7.2.amzn2 will be installed ---> Package flac-libs.x86_64 0:1.3.0-5.amzn2.0.2 will be installed ---> Package gsm.x86_64 0:1.0.13-11.amzn2.0.2 will be installed ---> Package libogg.x86_64 2:1.3.0-7.amzn2.0.2 will be installed ---> Package libvorbis.x86_64 1:1.3.3-8.amzn2.0.2 will be installed ---> Package polkit.x86_64 0:0.112-22.amzn2.1 will be installed --> Processing Dependency: polkit-pkla-compat for package: polkit-0.112-22.amzn2.1.x86_64 --> Processing Dependency: libmozjs-17.0.so(mozjs_17.0)(64bit) for package: polkit-0.112-22.amzn2.1.x86_64 --> Processing Dependency: libmozjs-17.0.so()(64bit) for package: polkit-0.112-22.amzn2.1.x86_64 --> Running transaction check ---> Package mozjs17.x86_64 0:17.0.0-20.amzn2.0.1 will be installed ---> Package polkit-pkla-compat.x86_64 0:0.1-4.amzn2.0.2 will be installed --> Finished Dependency Resolution Dependencies Resolved ============================================================================================================================================================================================ Package Arch Version Repository Size ============================================================================================================================================================================================ Installing: apache-maven noarch 3.5.2-1.el6 epel-apache-maven 8.1 M Installing for dependencies: GConf2 x86_64 3.2.6-8.amzn2.0.2 amzn2-core 1.0 M dbus-glib x86_64 0.100-7.2.amzn2 amzn2-core 103 k flac-libs x86_64 1.3.0-5.amzn2.0.2 amzn2-core 168 k gsm x86_64 1.0.13-11.amzn2.0.2 amzn2-core 30 k java-1.7.0-openjdk x86_64 1:1.7.0.241-2.6.20.0.amzn2.0.2 amzn2-core 255 k java-1.7.0-openjdk-devel x86_64 1:1.7.0.241-2.6.20.0.amzn2.0.2 amzn2-core 9.2 M java-1.7.0-openjdk-headless x86_64 1:1.7.0.241-2.6.20.0.amzn2.0.2 amzn2-core 26 M libasyncns x86_64 0.8-7.amzn2.0.2 amzn2-core 26 k libogg x86_64 2:1.3.0-7.amzn2.0.2 amzn2-core 24 k libsndfile x86_64 1.0.25-10.amzn2.0.2 amzn2-core 152 k libvorbis x86_64 1:1.3.3-8.amzn2.0.2 amzn2-core 204 k mozjs17 x86_64 17.0.0-20.amzn2.0.1 amzn2-core 1.4 M polkit x86_64 0.112-22.amzn2.1 amzn2-core 171 k polkit-pkla-compat x86_64 0.1-4.amzn2.0.2 amzn2-core 39 k pulseaudio-libs x86_64 10.0-3.amzn2.0.2 amzn2-core 651 k Transaction Summary ============================================================================================================================================================================================ Install 1 Package (+15 Dependent packages) Total download size: 47 M Installed size: 159 M Downloading packages: (1/16): dbus-glib-0.100-7.2.amzn2.x86_64.rpm | 103 kB 00:00:00 (2/16): GConf2-3.2.6-8.amzn2.0.2.x86_64.rpm | 1.0 MB 00:00:00 (3/16): gsm-1.0.13-11.amzn2.0.2.x86_64.rpm | 30 kB 00:00:00 (4/16): flac-libs-1.3.0-5.amzn2.0.2.x86_64.rpm | 168 kB 00:00:00 (5/16): java-1.7.0-openjdk-1.7.0.241-2.6.20.0.amzn2.0.2.x86_64.rpm | 255 kB 00:00:00 (6/16): java-1.7.0-openjdk-devel-1.7.0.241-2.6.20.0.amzn2.0.2.x86_64.rpm | 9.2 MB 00:00:00 (7/16): libasyncns-0.8-7.amzn2.0.2.x86_64.rpm | 26 kB 00:00:00 (8/16): libogg-1.3.0-7.amzn2.0.2.x86_64.rpm | 24 kB 00:00:00 (9/16): libsndfile-1.0.25-10.amzn2.0.2.x86_64.rpm | 152 kB 00:00:00 (10/16): libvorbis-1.3.3-8.amzn2.0.2.x86_64.rpm | 204 kB 00:00:00 (11/16): mozjs17-17.0.0-20.amzn2.0.1.x86_64.rpm | 1.4 MB 00:00:00 (12/16): polkit-0.112-22.amzn2.1.x86_64.rpm | 171 kB 00:00:00 (13/16): polkit-pkla-compat-0.1-4.amzn2.0.2.x86_64.rpm | 39 kB 00:00:00 (14/16): pulseaudio-libs-10.0-3.amzn2.0.2.x86_64.rpm | 651 kB 00:00:00 (15/16): java-1.7.0-openjdk-headless-1.7.0.241-2.6.20.0.amzn2.0.2.x86_64.rpm | 26 MB 00:00:00 (16/16): apache-maven-3.5.2-1.el6.noarch.rpm | 8.1 MB 00:00:04 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Total 9.8 MB/s | 47 MB 00:00:04 Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : 2:libogg-1.3.0-7.amzn2.0.2.x86_64 1/16 Installing : 1:libvorbis-1.3.3-8.amzn2.0.2.x86_64 2/16 Installing : flac-libs-1.3.0-5.amzn2.0.2.x86_64 3/16 Installing : mozjs17-17.0.0-20.amzn2.0.1.x86_64 4/16 Installing : polkit-0.112-22.amzn2.1.x86_64 5/16 Installing : polkit-pkla-compat-0.1-4.amzn2.0.2.x86_64 6/16 Installing : gsm-1.0.13-11.amzn2.0.2.x86_64 7/16 Installing : libsndfile-1.0.25-10.amzn2.0.2.x86_64 8/16 Installing : dbus-glib-0.100-7.2.amzn2.x86_64 9/16 Installing : GConf2-3.2.6-8.amzn2.0.2.x86_64 10/16 Installing : 1:java-1.7.0-openjdk-headless-1.7.0.241-2.6.20.0.amzn2.0.2.x86_64 11/16 Installing : libasyncns-0.8-7.amzn2.0.2.x86_64 12/16 Installing : pulseaudio-libs-10.0-3.amzn2.0.2.x86_64 13/16 Installing : 1:java-1.7.0-openjdk-1.7.0.241-2.6.20.0.amzn2.0.2.x86_64 14/16 Installing : 1:java-1.7.0-openjdk-devel-1.7.0.241-2.6.20.0.amzn2.0.2.x86_64 15/16 Installing : apache-maven-3.5.2-1.el6.noarch 16/16 Verifying : libasyncns-0.8-7.amzn2.0.2.x86_64 1/16 Verifying : polkit-0.112-22.amzn2.1.x86_64 2/16 Verifying : 1:libvorbis-1.3.3-8.amzn2.0.2.x86_64 3/16 Verifying : GConf2-3.2.6-8.amzn2.0.2.x86_64 4/16 Verifying : 1:java-1.7.0-openjdk-1.7.0.241-2.6.20.0.amzn2.0.2.x86_64 5/16 Verifying : apache-maven-3.5.2-1.el6.noarch 6/16 Verifying : dbus-glib-0.100-7.2.amzn2.x86_64 7/16 Verifying : 1:java-1.7.0-openjdk-headless-1.7.0.241-2.6.20.0.amzn2.0.2.x86_64 8/16 Verifying : pulseaudio-libs-10.0-3.amzn2.0.2.x86_64 9/16 Verifying : 2:libogg-1.3.0-7.amzn2.0.2.x86_64 10/16 Verifying : polkit-pkla-compat-0.1-4.amzn2.0.2.x86_64 11/16 Verifying : flac-libs-1.3.0-5.amzn2.0.2.x86_64 12/16 Verifying : libsndfile-1.0.25-10.amzn2.0.2.x86_64 13/16 Verifying : gsm-1.0.13-11.amzn2.0.2.x86_64 14/16 Verifying : mozjs17-17.0.0-20.amzn2.0.1.x86_64 15/16 Verifying : 1:java-1.7.0-openjdk-devel-1.7.0.241-2.6.20.0.amzn2.0.2.x86_64 16/16 Installed: apache-maven.noarch 0:3.5.2-1.el6 Dependency Installed: GConf2.x86_64 0:3.2.6-8.amzn2.0.2 dbus-glib.x86_64 0:0.100-7.2.amzn2 flac-libs.x86_64 0:1.3.0-5.amzn2.0.2 gsm.x86_64 0:1.0.13-11.amzn2.0.2 java-1.7.0-openjdk.x86_64 1:1.7.0.241-2.6.20.0.amzn2.0.2 java-1.7.0-openjdk-devel.x86_64 1:1.7.0.241-2.6.20.0.amzn2.0.2 java-1.7.0-openjdk-headless.x86_64 1:1.7.0.241-2.6.20.0.amzn2.0.2 libasyncns.x86_64 0:0.8-7.amzn2.0.2 libogg.x86_64 2:1.3.0-7.amzn2.0.2 libsndfile.x86_64 0:1.0.25-10.amzn2.0.2 libvorbis.x86_64 1:1.3.3-8.amzn2.0.2 mozjs17.x86_64 0:17.0.0-20.amzn2.0.1 polkit.x86_64 0:0.112-22.amzn2.1 polkit-pkla-compat.x86_64 0:0.1-4.amzn2.0.2 pulseaudio-libs.x86_64 0:10.0-3.amzn2.0.2 Complete! [ec2-user@bastin]$ [ec2-user@bastin]$ mvn --version Apache Maven 3.5.2 (138edd61fd100ec658bfa2d307c43b76940a5d7d; 2017-10-18T07:58:13Z) Maven home: /usr/share/apache-maven Java version: 1.8.0_222, vendor: Oracle Corporation Java home: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.222.b10-0.amzn2.0.1.x86_64/jre Default locale: en_US, platform encoding: UTF-8 OS name: "linux", version: "4.14.152-127.182.amzn2.x86_64", arch: "amd64", family: "unix" [ec2-user@bastin]$ [ec2-user@bastin]$ [ec2-user@bastin]$ 参考 Install Maven with Yum on Amazon Linux https://gist.github.com/sebsto/19b99f1fa1f32cae5d00 --- ### PostgreSQLの監視のためのログ設定について date: 2020-03-08 url: https://zatoima.github.io/postgresql-about-monitoring-log.html tags: PostgreSQL はじめに 監視には「レスポンス問題発生の予測」、「問題発生時の原因特定」という大きな目的があります。定期的なデータベース稼働に関するヘルスチェックを行う場合に、必要な情報が取得出来ていなければなりません。今回はログ出力の観点から代表的なPostgreSQLのログ管理の代表的なパラメータをまとめてみます。 バージョン情報 pgbench=# select version(); version ---------------------------------------------------------------------------------------------------------- PostgreSQL 10.11 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39), 64-bit (1 row) log関連の代表的なパラメータ一覧 パラメータ名 観点 デフォルト値 内容 log_destination ログ取得・配置 stderr stderr,csvlog,syslogの設定 logging_collector ログ取得・配置 on stderr,csvlogの内容をリダイレクトするかどうか log_directory ログ取得・配置 log どのディレクトリにログ・ファイルを格納するか log_filename ログ取得・配置 postgresql-%a.log ファイル名の指定 client_min_messages ログ取得タイミング notice クライアントに送信するレベル設定。DEBUG5、 DEBUG4、DEBUG3、DEBUG2、 DEBUG1、LOG、NOTICE、 WARNING、ERROR、FATAL、およびPANICから選ぶ。 log_min_messages ログ取得タイミング warning サーバログに書き込むためのレベル設定。DEBUG5、 DEBUG4、DEBUG3、DEBUG2、 DEBUG1、LOG、NOTICE、 WARNING、ERROR、FATAL、およびPANICから選ぶ。 log_min_error_statement ログ取得タイミング error サーバログにエラーとなったSQLを書き込む際のレベル設定 log_min_duration_statement ログ取得タイミング -1 指定した以上に実行に時間が掛かったSQLをサーバログに書き込むための設定。単位はミリ秒。 log_temp_files ログ取得タイミング -1 指定したサイズ以上の一時ファイルが作成された場合ログに記録。単位はKB。 log_statement ログ取得タイミング -1 どのSQL文をログに記録するかを制御します。 有効な値は、none(off)、ddl、mod、およびall(全てのメッセージ)。modは、全てのddl文に加え、INSERT、UPDATE、DELETE、TRUNCATE、およびCOPY FROMといった、データ変更文をログに記録。 PREPAREとEXPLAIN ANALYZEコマンドも、そこに含まれるコマンドが適切な種類であればログが取得。 log_checkpoints ログ取得対象 off チェックポイントに関する情報を出力する log_connections/log_disconnections ログ取得対象 off サーバへの接続/切断情報を記載する log_lock_waits ログ取得対象 off ロック獲得のために一定時間待たされた場合に出力する。時間はdeadlock_timeoutパラメータで指定。 log_line_prefix ログ取得対象 %m [%p] 各ログの先頭に出力する情報を設定。 %u:ユーザ名、%d:データベース名、%r:ホスト名/IPアドレス、ポート番号、%m:ミリ秒付きタイムスタンプ log_rotation_age ログメンテナンス 1d 指定した時間でログ・ファイルをハウスキーピングする log_rotation_size ログメンテナンス 0 指定したサイズでログ・ファイルをハウスキーピングする log_truncate_on_rotation ログメンテナンス on ハウスキーピング時に同じログ・ファイルが存在する場合に追記するか上書きするか設定 log_file_mode その他 600 ログ・ファイルのパーミッションを指定 全パラメータはマニュアルをご参照ください。 19.8. エラー報告とログ取得 https://www.postgresql.jp/document/10/html/runtime-config-logging.html postgresql.conf デフォルトの監視設定は最低限です。スロークエリの監視、チェックポイント頻度の監視、接続情報、一時ファイルの生成頻度、生成量の監視は必要かと思います。あとはファイル名、及びファイルに書き込まれる接頭辞は必要に応じて変更してもらえれば良いと思います。"#“にてコメントしているところはデフォルトから変更しているところとなります。 log_destination=stderr logging_collector=on log_directory=log log_filename='postgresql-%Y%m%d.log' #ファイル名の変更 client_min_messages=notice log_min_messages=warning log_min_error_statement=error log_min_duration_statement=3000 #スロークエリの検知 log_checkpoints=on #チェックポイントの頻度の確認のために有効化 log_connections=on #クライアントからの接続情報をログに書き込む log_disconnections=on #クライアントからの切断情報をログに書き込む log_temp_files=1024 #一時ファイル生成時にログに書き込む log_statement=ddl #DDLの実行をログに書き込む log_lock_waits=off log_line_prefix='[%t]%u %d %p[%l] ' #接頭辞のカスタマイズ log_rotation_age=1d log_rotation_size=0 log_truncate_on_rotation=on log_file_mode=0644 #postgresユーザ以外に読取り権限を付与。ログ監視を想定。 デフォルトから変更した一つ一つパラメータの効果を見ていきます。 ファイル名の変更 ▶ log_filename=‘postgresql-%Y%m%d.log’ ファイル名に日付が付くようになりました。 -rw-r----- 1 postgres postgres 534 Mar 3 03:05 postgresql-20200303.log スロークエリの検知 ▶ log_min_duration_statement=3000 設定した3000ミリ秒(3秒)以上のクエリを実行した場合、下記のようにSQL文とdurationが出力されます。実行計画を合わせて確認したい場合は、auro_explainの拡張機能と合わせてどうぞ。 [2020-03-03 03:15:03 UTC]postgres postgres 2457[13] LOG: duration: 6695.655 ms statement: select count(*) from t1,t2; PostgreSQLのauto_explainで特定クエリの実行計画を出力する | my opinion is my own https://zatoima.github.io/postgresql-about-auto_explain.html チェックポイントの頻度の確認のために有効化 ▶ log_checkpoints チェックポイントに関する情報が出力されます。 [2020-03-03 03:40:43 UTC] 2558[3] LOG: checkpoint starting: time [2020-03-03 03:41:12 UTC] 2558[4] LOG: checkpoint complete: wrote 289 buffers (1.8%); 0 WAL file(s) added, 0 removed, 0 recycled; write=28.864 s, sync=0.000 s, total=28.869 s; sync files=24, longest=0.000 s, average=0.000 s; distance=3312 kB, estimate=3312 kB クライアントからの接続情報 ▶ log_connections [2020-03-03 03:13:20 UTC][unknown] [unknown] 2450[1] LOG: connection received: host=[local] [2020-03-03 03:13:20 UTC]postgres postgres 2450[2] LOG: connection authorized: user=postgres database=postgres クライアントからの切断情報 ▶ log_disconnections [2020-03-03 03:14:04 UTC]postgres postgres 2450[3] LOG: disconnection: session time: 0:00:44.331 user=postgres database=postgres host=[local] 一時ファイル生成時にログに書き込む ▶ log_temp_files 省略。 DDLの実行をログに書き込む ▶ log_statement [2020-03-03 03:23:12 UTC]postgres postgres 2567[11] LOG: statement: create table t3(a numeric); 接頭辞のカスタマイズ ▶ log_line_prefix [2020-03-03 03:13:20 UTC]postgres postgres 2450[2]が出るようになった。接続元が仮に多い場合はホスト名も出るように設定しても良いかも。 [2020-03-03 03:13:20 UTC]postgres postgres 2450[2] LOG: connection authorized: user=postgres database=postgres postgresユーザ以外に読取り権限を付与 ▶ log_file_mode groupに読取り権限が付くようになりました。 -rw-r----- 1 postgres postgres 534 Mar 3 03:05 postgresql-20200303.log --- ### Aurora(PostgreSQL互換)で使用可能な拡張機能一覧 date: 2020-03-07 url: https://zatoima.github.io/aws-aurora-postgres-extention-list/ tags: Aurora, AWS, PostgreSQL 明示的なドキュメントは無かったが、RDS(PostgreSQL)と同等の方法で取得可能なはず。 Amazon RDS for PostgreSQL のバージョンと拡張機能 https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html#PostgreSQL.Concepts 使用可能な拡張機能はパラメータグループに定義されているのでそこから確認可能。 バージョン postgres=> select aurora_version(); aurora_version ---------------- 2.3.5 (1 row) postgres=> select version(); version ----------------------------------------------------------------------------- PostgreSQL 10.7 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.9.3, 64-bit (1 row) 拡張機能の表示 postgres=> show rds.extensions; rds.extensions -------------------------------------------------------------------------------------------------------- amcheck,address_standardizer,address_standardizer_data_us,apg_plan_mgmt,aurora_stat_utils,aws_commons,aws_ml,aws_s3,bloom,btree_gin,btree_gist,chkpass,citext,cube,dblink,dict_int,dict_xsy n,earthdistance,fuzzystrmatch,hll,hstore,hstore_plperl,intagg,intarray,ip4r,isn,log_fdw,ltree,orafce,pgaudit,pgcrypto,pgrouting,pgrowlocks,pgstattuple,pg_buffercache,pg_freespacemap,pg_hin t_plan,pg_similarity,pg_prewarm,pg_repack,pg_stat_statements,pg_trgm,pg_visibility,plcoffee,plls,plperl,plpgsql,plprofiler,pltcl,plv8,postgis,postgis_tiger_geocoder,postgis_topology,postgr es_fdw,prefix,sslinfo,tablefunc,test_parser,tsearch2,tsm_system_rows,tsm_system_time,unaccent,uuid-ossp (1 row) もしくは aws rds describe-engine-default-cluster-parameters --db-parameter-group-family aurora-postgresql10 もしくは select * FROM pg_available_extensions order by 1; postgres=> select * FROM pg_available_extensions order by 1; name | default_version | installed_version | comment ------------------------------+-----------------+-------------------+--------------------------------------------------------------------------------------------------------------------- address_standardizer | 2.4.4 | | Used to parse an address into constituent elements. Generally used to support geocoding address normalization step. address_standardizer_data_us | 2.4.4 | | Address Standardizer US dataset example amcheck | 1.0 | | functions for verifying relation integrity apg_plan_mgmt | 1.0.1 | | Amazon Aurora with PostgreSQL compatibility Query Plan Management aurora_stat_utils | 1.0 | | Statistics utility functions aws_commons | 1.0 | | Common data types across AWS services aws_s3 | 1.0 | | AWS S3 extension for importing data from S3 でrds.extensionsを確認する。pg_available_extensionsが一番見やすいかもしれない。 対応している拡張機能一覧 Extention Module amcheck address_standardizer address_standardizer_data_us apg_plan_mgmt aurora_stat_utils aws_commons aws_ml aws_s3 bloom btree_gin btree_gist chkpass citext cube dblink dict_int dict_xsyn earthdistance fuzzystrmatch hll hstore hstore_plperl intagg intarray ip4r isn log_fdw ltree orafce pgaudit pgcrypto pgrouting pgrowlocks pgstattuple pg_buffercache pg_freespacemap pg_hint_plan pg_similarity pg_prewarm pg_repack pg_stat_statements pg_trgm pg_visibility plcoffee plls plperl plpgsql plprofiler pltcl plv8 postgis postgis_tiger_geocoder postgis_topology postgres_fdw prefix sslinfo tablefunc test_parser tsearch2 tsm_system_rows tsm_system_time unaccent uuid-ossp --- ### PostgreSQLのoid2nameの使用方法 date: 2020-03-06 url: https://zatoima.github.io/postgresql-how-to-use-oid2name/ tags: PostgreSQL オブジェクト識別子(oid)とは、PostgreSQLがDB内部に格納している様々なオブジェクト(テーブルやインデックス、関数、演算子、データ型定義などなど)を一意に識別するためのID。 8.18. オブジェクト識別子データ型 https://www.postgresql.jp/document/10/html/datatype-oid.html oidをOS側から見たい時に使用するoid2nameの使い方メモ。 ヘルプ表示 -bash-4.2$ oid2name -h oid2name helps examining the file structure used by PostgreSQL. Usage: oid2name [OPTION]... Options: -d DBNAME database to connect to -f FILENODE show info for table with given file node -H HOSTNAME database server host or socket directory -i show indexes and sequences too -o OID show info for table with given OID -p PORT database server port number -q quiet (don't show headers) -s show all tablespaces -S show system objects too -t TABLE show info for named table -U NAME connect as specified database user -V, --version output version information, then exit -x extended (show additional columns) -?, --help show this help, then exit The default action is to show all database OIDs. Report bugs to <pgsql-bugs@postgresql.org>. 引数無しで実行 -bash-4.2$ oid2name All databases: Oid Database Name Tablespace ---------------------------------- 16456 pgbench pg_default 16392 pgtest pg_default 13865 postgres pg_default 13864 template0 pg_default 1 template1 pg_default テーブルスペース単位で実行 -bash-4.2$ oid2name -s All tablespaces: Oid Tablespace Name ----------------------- 1663 pg_default 1664 pg_global 特定データベースを指定して実行 -bash-4.2$ oid2name -d pgbench From database "pgbench": Filenode Table Name ---------------------------- 16469 pgbench_accounts 16466 pgbench_branches 16479 pgbench_history 16460 pgbench_tellers インデックスも追加で表示 -bash-4.2$ oid2name -d pgbench -i From database "pgbench": Filenode Table Name --------------------------------- 16469 pgbench_accounts 16474 pgbench_accounts_pkey 16466 pgbench_branches 16470 pgbench_branches_pkey 16479 pgbench_history 16460 pgbench_tellers 16472 pgbench_tellers_pkey 特定データベースの特定テーブルを指定 -bash-4.2$ oid2name -d pgbench -t pgbench_accounts From database "pgbench": Filenode Table Name ---------------------------- 16469 pgbench_accounts --- ### PostgreSQLのpg_buffercacheを使用して共有buffer上のオブジェクトを確認する date: 2020-03-05 url: https://zatoima.github.io/postgresql-about-pg_buffercache.html tags: PostgreSQL はじめに contribモジュールにpg_buffercacheというPostgreSQLのバッファ・キャッシュの使用状況を確認できる拡張機能がありますので使ってみます。Oracleでいうところのx$bh表かな、と思っています。 バージョンについて postgres=# select version(); version ---------------------------------------------------------------------------------------------------------- PostgreSQL 10.11 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39), 64-bit (1 row) pg_buffercacheのインストール postgres=# CREATE EXTENSION pg_buffercache; CREATE EXTENSION postgres=# \dx List of installed extensions Name | Version | Schema | Description --------------------+---------+------------+----------------------------------------------------------- pg_buffercache | 1.3 | public | examine the shared buffer cache pg_stat_statements | 1.6 | public | track execution statistics of all SQL statements executed plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language (3 rows) postgres=# postgres=# \dx+ Objects in extension "pg_buffercache" Object description --------------------------------- function pg_buffercache_pages() view pg_buffercache (2 rows) pg_buffercacheはcontribモジュールの一つなので必要に応じてcontribのインストールも実施が必要です。 sudo yum -y install postgresql10-devel postgresql10-contrib 使用方法 pg_buffercacheは1行ごとに各バッファの情報が記載されます。したがって、1バッファページは8KB単位となるので、shared_buffersが128MBの場合はページ数は16384となります。 postgres=# show shared_buffers; shared_buffers ---------------- 128MB (1 row) postgres=# SELECT count(*) FROM pg_buffercache; count ------- 16384 (1 row) pg_buffercacheビューの各列の説明は次の通りです。 postgres=# \d pg_buffercache View "public.pg_buffercache" Column | Type | Collation | Nullable | Default ------------------+----------+-----------+----------+--------- bufferid | integer | | | relfilenode | oid | | | reltablespace | oid | | | reldatabase | oid | | | relforknumber | smallint | | | relblocknumber | bigint | | | isdirty | boolean | | | usagecount | smallint | | | pinning_backends | integer | | | 名前 型 参照 説明 bufferid integer 1からshared_buffersまでの範囲で示されるID relfilenode oid pg_class.relfilenode リレーションのファイルノード番号 reltablespace oid pg_tablespace.oid リレーションのテーブル空間OID reldatabase oid pg_database.oid リレーションのデータベースOID relforknumber smallint リレーション内のフォーク番号。include/common/relpath.h参照 relblocknumber bigint リレーション内のページ番号 isdirty boolean ダーティページかどうか usagecount smallint Clock-sweepアクセスカウント pinning_backends integer このバッファをピン留めしているバックエンドの数 テーブルごとのバッファページ数を集計 SELECT c.relname, COUNT(*) AS buffers FROM pg_buffercache b INNER JOIN pg_class c ON b.relfilenode = pg_relation_filenode(c.oid) AND b.reldatabase IN(0,( SELECT oid FROM pg_database WHERE datname = current_database() )) GROUP BY c.relname ORDER BY 2 DESC LIMIT 10 ; 出力結果 relname | buffers -----------------------+--------- pgbench_accounts | 1644 pgbench_accounts_pkey | 276 pg_proc | 78 pg_depend | 59 pg_toast_2618 | 56 pg_attribute | 53 pg_collation | 53 pg_description | 43 test | 35 pg_statistic | 35 (10 rows) データベース、テーブルごとのバッファページ数を集計 SELECT d.datname, c.relname, count(*) FROM pg_buffercache b LEFT OUTER JOIN ( SELECT oid, * FROM pg_database WHERE oid = 0 OR datname = current_database() ) AS d ON b.reldatabase = d.oid LEFT OUTER JOIN pg_class c ON b.relfilenode = c.relfilenode GROUP BY d.datname, c.relname ORDER BY d.datname, c.relname ; 出力結果 datname | relname | count ----------+------------------------------------------+------- postgres | pg_aggregate | 6 postgres | pg_aggregate_fnoid_index | 2 postgres | pg_am | 5 postgres | pg_amop | 10 postgres | pg_amop_fam_strat_index | 4 postgres | pg_amop_opr_fam_index | 4 postgres | pg_amproc | 8 postgres | pg_amproc_fam_proc_index | 4 postgres | pg_amproc_oid_index | 3 postgres | pg_attrdef_adrelid_adnum_index | 1 ダーティー状態でまだ書き込まれていないバッファ情報を取得 SELECT c.relname, count(*) AS buffers FROM pg_buffercache b INNER JOIN pg_class c ON b.relfilenode = pg_relation_filenode(c.oid) AND b.reldatabase IN (0, (SELECT oid FROM pg_database WHERE datname = current_database())) AND b.isdirty = true GROUP BY c.relname ORDER BY 2 DESC LIMIT 100; 出力結果 relname | buffers -----------------------------------+--------- pgbench_accounts | 1645 pgbench_accounts_pkey | 274 pgbench_history | 51 pgbench_branches | 13 pgbench_tellers | 10 pg_class | 1 pgbench_tellers_pkey | 1 pg_class_oid_index | 1 pg_class_relname_nsp_index | 1 pg_class_tblspc_relfilenode_index | 1 pgbench_branches_pkey | 1 (11 rows) checkpoint を発行すると当然ダーティーページはなくなります。 postgres=# checkpoint; CHECKPOINT postgres=# postgres=# SELECT c.relname, count(*) AS buffers FROM pg_buffercache b INNER JOIN pg_class c ON b.relfilenode = pg_relation_filenode(c.oid) AND b.reldatabase IN (0, (SELECT oid FROM pg_database WHERE datname = current_database())) AND b.isdirty = true GROUP BY c.relname ORDER BY 2 DESC LIMIT 100; relname | buffers ---------+--------- (0 rows) postgres=# どのくらいの共有バッファが未使用か 未使用のバッファはnullなのでcountの引数を変えることで確認可能なはず。 postgres=# select count(*) as shared_buffer_count, COUNT(relfilenode) as free_in_use_count, count(*) - COUNT(relfilenode) as free_buffer_count from pg_buffercache; shared_buffer_count | free_in_use_count | free_buffer_count ---------------------+-------------------+------------------- 16384 | 7093 | 9291 (1 row) 参考 F.25. pg_buffercache https://www.postgresql.jp/document/10/html/pgbuffercache.html PostgreSQL Deep Dive: pg_buffercacheで共有バッファを覗いてみる http://pgsqldeepdive.blogspot.com/2012/12/pgbuffercache.html --- ### PostgreSQLのpgstattupleのインストールと使用方法 date: 2020-03-04 url: https://zatoima.github.io/postgresql-how-to-install-and-use-pgstattuple/ tags: PostgreSQL pgstattupleでタプルレベルの統計情報を確認することが出来ます。タプル総数、テーブルの大きさ、デットタプルの総数や空き容量を知ることが出来ます。 バージョン情報 pgbench=# select version(); version ---------------------------------------------------------------------------------------------------------- PostgreSQL 10.11 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39), 64-bit (1 row) インストール pgbench=# CREATE EXTENSION pgstattuple; CREATE EXTENSION pgbench=# \dx List of installed extensions Name | Version | Schema | Description -------------+---------+------------+------------------------------ pgstattuple | 1.5 | public | show tuple-level statistics plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language (2 rows) pgbench=# pgbench=# pgbench=# \dx+ Objects in extension "pgstattuple" Object description --------------------------------------- function pg_relpages(regclass) function pg_relpages(text) function pgstatginindex(regclass) function pgstathashindex(regclass) function pgstatindex(regclass) function pgstatindex(text) function pgstattuple_approx(regclass) function pgstattuple(regclass) function pgstattuple(text) (9 rows) pgstattupleはcontribモジュールの一つなので必要に応じてcontribのインストールも実施が必要です。 sudo yum -y install postgresql10-devel postgresql10-contrib 使用方法 特定テーブルの情報取得 pgbench=# \dt List of relations Schema | Name | Type | Owner --------+------------------+-------+---------- public | pgbench_accounts | table | postgres public | pgbench_branches | table | postgres public | pgbench_history | table | postgres public | pgbench_tellers | table | postgres (4 rows) pgbench=# SELECT * FROM pgstattuple('pgbench_accounts'); table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent -----------+-------------+-----------+---------------+------------------+----------------+--------------------+------------+-------------- 14712832 | 100000 | 12100000 | 82.24 | 3488 | 422048 | 2.87 | 569468 | 3.87 (1 row) 各列の説明 列 型 説明 table_len bigint リレーションのバイト単位の物理長 tuple_count bigint 有効なタプル数 tuple_len bigint 有効なタプルの物理長(バイト単位) tuple_percent float8 有効タプルの割合 dead_tuple_count bigint 無効なタプル数 dead_tuple_len bigint バイト単位の総不要タプル長 dead_tuple_percent float8 不要タプルの割合 free_space bigint バイト単位の総空き領域 free_percent float8 空き領域の割合 特定インデックスの情報取得 pgbench=# \di List of relations Schema | Name | Type | Owner | Table --------+-----------------------+-------+----------+------------------ public | pgbench_accounts_pkey | index | postgres | pgbench_accounts public | pgbench_branches_pkey | index | postgres | pgbench_branches public | pgbench_tellers_pkey | index | postgres | pgbench_tellers (3 rows) pgbench=# SELECT * FROM pgstatindex('pgbench_accounts_pkey'); version | tree_level | index_size | root_block_no | internal_pages | leaf_pages | empty_pages | deleted_pages | avg_leaf_density | leaf_fragmentation ---------+------------+------------+---------------+----------------+------------+-------------+---------------+------------------+-------------------- 2 | 1 | 2260992 | 3 | 1 | 274 | 0 | 0 | 94.57 | 0 (1 row) 列 型 説明 version integer B-treeバージョン番号 tree_level integer ルートページのツリーレベル index_size bigint インデックス内の総ページ数 root_block_no bigint ルートブロックの場所 internal_pages bigint “内部”(上位レベル)ページ数 leaf_pages bigint リーフページ数 empty_pages bigint 空ページ数 deleted_pages bigint 削除ページ数 avg_leaf_density float8 リーフページの平均密度 leaf_fragmentation float8 リーフページの断片化 その他 pgstattuple、pgstatindexは常に全件走査(Full Scan)を実行してテーブル、インデックスの情報を収集するためタイミングには注意が必要。全件走査(Full Scan)を避けたい場合はpgstattuple_approx関数を使う手もある。 参考 F.31. pgstattuple https://www.postgresql.jp/document/10/html/pgstattuple.html --- ### PostgreSQLのauto_explainで特定クエリの実行計画を出力する date: 2020-03-03 url: https://zatoima.github.io/postgresql-about-auto_explain.html tags: PostgreSQL はじめに contribモジュールにauto_explain という特定の条件にマッチしたクエリの実行計画をログに出力する拡張機能がありますので使ってみます。スロークエリの監視と改善を行う場合に有効な拡張機能だと思います。 auto_explainはcontribモジュールの一つなので必要に応じてcontribのインストールも実施が必要です。 sudo yum -y install postgresql10-devel postgresql10-contrib バージョンについて postgres=# select version(); version ---------------------------------------------------------------------------------------------------------- PostgreSQL 10.11 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39), 64-bit (1 row) pg_buffercacheの設定 postgresql.confに下記のパラメータを設定します。auto_explain.log_min_durationにて指定した秒数以上のクエリの実行計画がサーバログに出力されます。ここの設定値は要件に応じて変更する必要があります。ここでは1秒以上としています。 shared_preload_libraries = 'auto_explain' auto_explain.log_min_duration = '1' auto_explain.log_analyze=on auto_explain.log_buffers=on auto_explain.log_verbose=on 関連パラメータ パラメータ 説明 auto_explain.log_min_duration 実行計画がログに記録されるようになる、ミリ秒単位の最小の文実行時間 auto_explain.log_analyze EXPLAIN出力ではなく、EXPLAIN ANALYZE出力を行う。極端に性能上のマイナスの影響が起こり得る。 auto_explain.log_buffers 実行計画のログを取得するときに、バッファ使用統計を出力するかどうかを制御。EXPLAINのBUFFERSオプションと同じ auto_explain.log_timing 実行計画のログが取得されたときに、ノード毎の時間的調整情報を出力するかどうかを制 auto_explain.log_triggers 実行計画のログを記録するときに、トリガ実行の統計を含める auto_explain.log_verbose 冗長な詳細が出力されるかどうかを制御します。 EXPLAINのVERBOSEオプションと同じ。 使用方法 クエリを実行します。10000件入っているテーブルを直積結合して件数をカウントしています。auto_explain.log_min_duration以上掛かるSQLである必要があります。 select count(*) from t1,t2; 2パターン実行しました。 パターン1.) shared_preload_libraries = ‘auto_explain’ auto_explain.log_min_duration = ‘1’ 2020-03-02 09:22:53.837 UTC [27039] LOG: duration: 6715.237 ms plan: Query Text: select count(*) from t1,t2; Aggregate (cost=1500353.00..1500353.01 rows=1 width=8) -> Nested Loop (cost=0.00..1250353.00 rows=100000000 width=0) -> Seq Scan on t1 (cost=0.00..164.00 rows=10000 width=0) -> Materialize (cost=0.00..214.00 rows=10000 width=0) -> Seq Scan on t2 (cost=0.00..164.00 rows=10000 width=0) パターン2.) shared_preload_libraries = ‘auto_explain’ auto_explain.log_min_duration = ‘1’ auto_explain.log_analyze=on auto_explain.log_buffers=on auto_explain.log_verbose=on 2020-03-02 09:36:56.407 UTC [27217] LOG: duration: 399369.613 ms plan: Query Text: select count(*) from t1,t2; Aggregate (cost=1500353.00..1500353.01 rows=1 width=8) (actual time=399369.587..399369.588 rows=1 loops=1) Output: count(*) Buffers: shared hit=128 -> Nested Loop (cost=0.00..1250353.00 rows=100000000 width=0) (actual time=0.020..297204.066 rows=100000000 loops=1) Buffers: shared hit=128 -> Seq Scan on public.t1 (cost=0.00..164.00 rows=10000 width=0) (actual time=0.007..18.548 rows=10000 loops=1) Output: t1.a, t1.b, t1.c, t1.d Buffers: shared hit=64 -> Materialize (cost=0.00..214.00 rows=10000 width=0) (actual time=0.002..10.057 rows=10000 loops=10000) Buffers: shared hit=64 -> Seq Scan on public.t2 (cost=0.00..164.00 rows=10000 width=0) (actual time=0.005..11.372 rows=10000 loops=1) Buffers: shared hit=64 パターン2の方が多くの情報が出力されます。ただ、auto_explain.log_analyze はマニュアルに、このパラメータが有効の場合、計画ノードごとの時間的調整は事実上ログされるまで如何に時間が掛かろうと、全ての実行文に対して引き起こります。 極端に性能上のマイナスの影響が起こり得ます。 と記載があります。今回は「6715.237 ms」と「399369.613 ms」という実行時間の差異が発生しました。ログ取得の影響で本番環境のクエリに影響を与えるのを本末転倒だと思うのでauto_explain.log_analyzeの設定にはご注意ください。 参考 F.4. auto_explain https://www.postgresql.jp/document/10/html/auto-explain.html --- ### DBpediaのデータ(turtle)をwgetで一括ダウンロード date: 2020-02-27 url: https://zatoima.github.io/dbpedia-jp-wget-download.html tags: DBpedia 日本語版のDBpediaの現時点の最新版である http://ja.dbpedia.org/dumps/20160407/ 配下の全データをwgetで再帰的に取得しています。「-np」は親ディレクトリを取得対象しないようにするためのオプションです。 wget -r -np -R "index.html?*" http://ja.dbpedia.org/dumps/20160407/ 取得結果 [ec2-user@bastin 20160407]$ pwd /home/ec2-user/dbpedia/ja.dbpedia.org/dumps/20160407 [ec2-user@bastin 20160407]$ du -sh 4.4G . [ec2-user@bastin 20160407]$ ls -l total 4306268 -rw-rw-r-- 1 ec2-user ec2-user 16381 Feb 25 01:26 index.html -rw-rw-r-- 1 ec2-user ec2-user 64620507 Apr 27 2016 jawiki-20160407-article-categories.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 36087466 Apr 27 2016 jawiki-20160407-article-categories.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 11199701 Apr 27 2016 jawiki-20160407-article-templates-nested.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 5854138 Apr 27 2016 jawiki-20160407-article-templates-nested.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 58951338 Apr 27 2016 jawiki-20160407-article-templates.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 29388098 Apr 27 2016 jawiki-20160407-article-templates.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 2441006 Apr 27 2016 jawiki-20160407-category-labels.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 1416295 Apr 27 2016 jawiki-20160407-category-labels.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 2047854 Apr 27 2016 jawiki-20160407-disambiguations-unredirected.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 1258154 Apr 27 2016 jawiki-20160407-disambiguations-unredirected.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 35396297 Apr 27 2016 jawiki-20160407-external-links.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 24184031 Apr 27 2016 jawiki-20160407-external-links.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 586677 Apr 27 2016 jawiki-20160407-geo-coordinates-mappingbased.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 390558 Apr 27 2016 jawiki-20160407-geo-coordinates-mappingbased.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 1052110 Apr 27 2016 jawiki-20160407-geo-coordinates.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 710988 Apr 27 2016 jawiki-20160407-geo-coordinates.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 3242564 Apr 27 2016 jawiki-20160407-homepages.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 2018246 Apr 27 2016 jawiki-20160407-homepages.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 25713177 Apr 27 2016 jawiki-20160407-images.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 18660941 Apr 27 2016 jawiki-20160407-images.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 146867252 Apr 27 2016 jawiki-20160407-infobox-properties-unredirected.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 106114414 Apr 27 2016 jawiki-20160407-infobox-properties-unredirected.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 539768 Apr 27 2016 jawiki-20160407-infobox-property-definitions.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 257668 Apr 27 2016 jawiki-20160407-infobox-property-definitions.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 91 Apr 27 2016 jawiki-20160407-infobox-test.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 92 Apr 27 2016 jawiki-20160407-infobox-test.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 6749954 Apr 27 2016 jawiki-20160407-instance-types.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 20605723 Apr 27 2016 jawiki-20160407-instance-types-transitive.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 12598132 Apr 27 2016 jawiki-20160407-instance-types-transitive.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 3302762 Apr 27 2016 jawiki-20160407-instance-types.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 777393 Apr 27 2016 jawiki-20160407-interlanguage-links.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 482555 Apr 27 2016 jawiki-20160407-interlanguage-links.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 30962284 Apr 27 2016 jawiki-20160407-labels.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 19374825 Apr 27 2016 jawiki-20160407-labels.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 23766215 Apr 27 2016 jawiki-20160407-mappingbased-literals.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 14463439 Apr 27 2016 jawiki-20160407-mappingbased-literals.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 28382739 Apr 27 2016 jawiki-20160407-mappingbased-objects-uncleaned-unredirected.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 16038031 Apr 27 2016 jawiki-20160407-mappingbased-objects-uncleaned-unredirected.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 26566377 Apr 27 2016 jawiki-20160407-out-degree.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 14217551 Apr 27 2016 jawiki-20160407-out-degree.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 34738422 Apr 27 2016 jawiki-20160407-page-ids.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 19564834 Apr 27 2016 jawiki-20160407-page-ids.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 28049111 Apr 27 2016 jawiki-20160407-page-length.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 15491318 Apr 27 2016 jawiki-20160407-page-length.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 569374886 Apr 27 2016 jawiki-20160407-page-links-unredirected.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 367564292 Apr 27 2016 jawiki-20160407-page-links-unredirected.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 33225236 Apr 27 2016 jawiki-20160407-page_props.sql.gz -rw-rw-r-- 1 ec2-user ec2-user 2285740564 Apr 27 2016 jawiki-20160407-pages-articles.xml.bz2 -rw-rw-r-- 1 ec2-user ec2-user 12735146 Apr 27 2016 jawiki-20160407-redirects.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 8214822 Apr 27 2016 jawiki-20160407-redirects.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 36232990 Apr 27 2016 jawiki-20160407-revision-ids.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 22263076 Apr 27 2016 jawiki-20160407-revision-ids.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 38797873 Apr 27 2016 jawiki-20160407-revision-uris.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 29276720 Apr 27 2016 jawiki-20160407-revision-uris.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 7261254 Apr 27 2016 jawiki-20160407-skos-categories.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 4328988 Apr 27 2016 jawiki-20160407-skos-categories.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 751735 Apr 27 2016 jawiki-20160407-specific-mappingbased-properties.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 381452 Apr 27 2016 jawiki-20160407-specific-mappingbased-properties.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 12460 Apr 27 2016 jawiki-20160407-topical-concepts-unredirected.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 7402 Apr 27 2016 jawiki-20160407-topical-concepts-unredirected.ttl.bz2 -rw-rw-r-- 1 ec2-user ec2-user 60923158 Apr 27 2016 jawiki-20160407-wikipedia-links.tql.bz2 -rw-rw-r-- 1 ec2-user ec2-user 37255115 Apr 27 2016 jawiki-20160407-wikipedia-links.ttl.bz2 drwxrwxr-x 2 ec2-user ec2-user 214 Feb 25 01:28 links [ec2-user@bastin 20160407]$ --- ### SPARQLを使用して英語版DBpediaからディープインパクトの始祖を辿る date: 2020-02-25 url: https://zatoima.github.io/sparql-graph-dbpedia-en-search.html tags: Graph, SPARQL, DBPedia, Neptune はじめに 下記記事のリベンジ記事です。有馬記念の勝ち馬からサラブレッドの始祖まで辿ろうとしたが、dbpedia-jp(jp.wikipedia.org)のURI誤りで途中で終わってしまった。 日本語版DBPediaで有馬記念の勝ち馬からサラブレッドの始祖を辿る | my opinion is my own https://zatoima.github.io/sparql-graph-thoroughbred-search.html リベンジとして、英語版のDBPediaを使いディープインパクトを起点として始祖まで辿ろうと思います。 競馬で走る馬はサラブレッドと呼ばれますが、血統を辿ると全て3頭の馬(ダーレーアラビアン、ゴドルフィンアラビアン、バイアリーターク)にさかのぼると言います。 3大始祖と世界の血統:サラブレッド講座 JRA http://www.jra.go.jp/kouza/thoroughbred/founder/ DBpedia(英語版) Virtuoso SPARQL Query Editor https://dbpedia.org/sparql SPARQLクエリ 最終的にこうしました。 述語部分はsireとなります。父という意味です。リーディングサイアー (Leading Sire)と言いますね。 PREFIX dbpedia: <http://dbpedia.org/ontology/> select ?parent_gen1_name ?parent_gen2_name ?parent_gen3_name ?parent_gen4_name ?parent_gen5_name ?parent_gen6_name ?parent_gen7_name ?parent_gen8_name ?parent_gen9_name ?parent_gen10_name ?parent_gen11_name ?parent_gen12_name ?parent_gen13_name ?parent_gen14_name ?parent_gen15_name ?parent_gen16_name ?parent_gen17_name ?parent_gen18_name ?parent_gen19_name ?parent_gen20_name ?parent_gen21_name ?parent_gen22_name ?parent_gen23_name ?parent_gen24_name ?parent_gen25_name where { <http://dbpedia.org/resource/Deep_Impact_(horse)> dbpedia:sire ?parent_gen1_name . ?parent_gen1_name dbpedia:sire ?parent_gen2_name . #Sunday_Silence ?parent_gen2_name dbpedia:sire ?parent_gen3_name . #Halo ?parent_gen3_name dbpedia:sire ?parent_gen4_name . #Hail_To_Reason ?parent_gen4_name dbpedia:sire ?parent_gen5_name . #Turn-To ?parent_gen5_name dbpedia:sire ?parent_gen6_name . #Royal_Charger ?parent_gen6_name dbpedia:sire ?parent_gen7_name . #Nearco ?parent_gen7_name dbpedia:sire ?parent_gen8_name . #Pharos ?parent_gen8_name dbpedia:sire ?parent_gen9_name . #Phalaris ?parent_gen9_name dbpedia:sire ?parent_gen10_name . #Polymelus ?parent_gen10_name dbpedia:sire ?parent_gen11_name . #Cyllene ?parent_gen11_name dbpedia:sire ?parent_gen12_name . #Bona_Vista ?parent_gen12_name dbpedia:sire ?parent_gen13_name . #Bend_Or ?parent_gen13_name dbpedia:sire ?parent_gen14_name . #Doncaster ?parent_gen14_name dbpedia:sire ?parent_gen15_name . #The_Baron ?parent_gen15_name dbpedia:sire ?parent_gen16_name . #Birdcatcher ?parent_gen16_name dbpedia:wikiPageRedirects ?Birdcatcher_wpr . ?Birdcatcher_wpr dbo:sire ?parent_gen17_name . #Sir_Hercules ?parent_gen17_name dbpedia:sire ?parent_gen18_name . #Whalebone ?parent_gen18_name dbpedia:sire ?parent_gen19_name . #Waxy ?parent_gen19_name dbpedia:sire ?parent_gen20_name . #Potoooooooo ?parent_gen20_name dbpedia:sire ?parent_gen21_name . #Eclipse ?parent_gen21_name dbpedia:sire ?parent_gen22_name . #Marske ?parent_gen22_name dbpedia:sire ?parent_gen23_name . #Squirt ?parent_gen23_name dbpedia:sire ?parent_gen24_name . #Bartlets_Childers ?parent_gen24_name dbpedia:wikiPageRedirects ?Bartlets_Childers . ?Bartlets_Childers dbo:sire ?parent_gen25_name . #Darley_Arabian } 補足 BirdcatcherとBartlets_Childersには他の競走馬にあるhttp://dbpedia.org/ontology/sireプロパティがなく、そこからは親を辿れません。 PREFIX dbpedia: <http://dbpedia.org/ontology/> select * where { <http://dbpedia.org/resource/Birdcatcher> ?p ?o . } 述語がhttp://dbpedia.org/ontology/wikiPageRedirectsのhttp://dbpedia.org/resource/Birdcatcher_(horse)に行くとdbo:sireがありましたのでこちらのPropertyを使用します。 こうすることでsireを取得することが出来ました。 PREFIX dbpedia: <http://dbpedia.org/ontology/> select ?Birdcatcher_sire where { <http://dbpedia.org/resource/Birdcatcher> dbpedia:wikiPageRedirects ?Birdcatcher_wpr . ?Birdcatcher_wpr dbo:sire ?Birdcatcher_sire } 結果 最終的な結果はこうなりました。ディープインパクトの始祖はDarley_Arabianとなります! 世代 馬名 1 Sunday_Silence 2 Halo 3 Hail_To_Reason 4 Turn-To 5 Royal_Charger 6 Nearco 7 Pharos 8 Phalaris 9 Polymelus 10 Cyllene 11 Bona_Vista 12 Bend_Or 13 Doncaster 14 Stockwell 15 The_Baron 16 Birdcatcher 17 Sir_Hercules 18 Whalebone 19 Waxy 20 Potoooooooo 21 Eclipse 22 Marske 23 Squirt 24 Bartlet’s_Childers 25 Darley_Arabian --- ### SPARQLを使用して日本語版DBPediaから有馬記念の勝ち馬の始祖を辿る date: 2020-02-22 url: https://zatoima.github.io/sparql-graph-thoroughbred-search.html tags: Graph, SPARQL, DBPedia, Neptune はじめに DBpediaはWikipediaから情報を抽出してLOD (Linked Open Data)として公開するコミュニティプロジェクトで、英語版と日本語版があります。日本語版はja.wikipedia.orgからデータを抽出しています。抽出したデータは構造化データ(RDF)として格納されています。RDFストアに対してはSPARQLというクエリ言語で情報を取得することが出来ます。今回は日本語版のDBpediaで情報を取得したいと思います。 DBpediaのエンドポイントはこちらになります。 Virtuoso SPARQL Query Editor http://ja.dbpedia.org/sparql 有馬記念の勝ち馬に関する情報 プロパティを調べる 勝ち馬を軸にまずはどんなプロパティを持っているかどうかを調べてみる。 select distinct ?p { { ?name prop-ja:wikiPageUsesTemplate template-ja:有馬記念勝ち馬. } ?name rdfs:label ?label ; ?p ?o . } サンプルを確認 勝ち馬を軸にまずはどんなプロパティを持っているかのサンプル値を出力する。 select ?p (SAMPLE(?o) AS ?sample_value) WHERE { { ?name prop-ja:wikiPageUsesTemplate template-ja:有馬記念勝ち馬. } ?name rdfs:label ?label ; ?p ?o . } order by (?p) 血統を辿る 次に父の父の父の父・・・・・という感じで血統を調べていき、どこまで辿れるかやってみます。 RDBMSに格納されているデータで同じように特定の馬の父の父の父とした場合、同じテーブルに格納されている値をサブクエリ(副問合せ)で結合して取得すると思いますが、おそらく数世代先の馬を調べる時に性能限界が来ると思います。何度もjoinする必要があるので。 一方、RDFストアやSPARQLクエリは関係性を抽出することに優れた言語のため、特にリレーション抽出対象が増えたとしてもクエリの性能に影響を与えません。 ちなみに競馬で走る馬はサラブレッドと呼ばれますが、血統を辿ると全て3頭の馬(ダーレーアラビアン、ゴドルフィンアラビアン、バイアリーターク)にさかのぼると言います。**WikipediaやDBPediaのデータが正しければ**おそらくこの3頭のどれかには辿り付くはずです。 3大始祖と世界の血統:サラブレッド講座 JRA http://www.jra.go.jp/kouza/thoroughbred/founder/ 第1世代 まずは勝ち馬の父を調べてみる。 select distinct ?parent_f_name (count(?parent_f_name) AS ?count) { { ?name prop-ja:wikiPageUsesTemplate template-ja:有馬記念勝ち馬. } ?name rdfs:label ?label ; prop-ja:父 ?parent_f_name . } ORDER BY DESC(?count) 第2世代 勝ち馬の父の父を調べてみる select distinct ?parent_f_f_name (count(?parent_f_f_name) AS ?count) { { ?name prop-ja:wikiPageUsesTemplate template-ja:有馬記念勝ち馬. } ?name rdfs:label ?label ; prop-ja:父 ?parent_f_name . ?parent_f_name prop-ja:父 ?parent_f_f_name . } ORDER BY DESC(?count) 第18世代 一気に飛んで第18世代です。こんな感じでどこまで辿れるか試してみます。ホエルボーンは1807年-1831年のイギリス馬です。現時点で18世代遡っています。 select distinct ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name (count(?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name) AS ?count) { { ?name prop-ja:wikiPageUsesTemplate template-ja:有馬記念勝ち馬. } ?name rdfs:label ?label ; prop-ja:父 ?parent_f_name . ?parent_f_name prop-ja:父 ?parent_f_f_name . ?parent_f_f_name prop-ja:父 ?parent_f_f_f_name . ?parent_f_f_f_name prop-ja:父 ?parent_f_f_f_f_name . ?parent_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_name . ?parent_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . } ORDER BY DESC(?count) 第19世代 select distinct ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name (count(?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name) AS ?count) { { ?name prop-ja:wikiPageUsesTemplate template-ja:有馬記念勝ち馬. } ?name rdfs:label ?label ; prop-ja:父 ?parent_f_name . ?parent_f_name prop-ja:父 ?parent_f_f_name . ?parent_f_f_name prop-ja:父 ?parent_f_f_f_name . ?parent_f_f_f_name prop-ja:父 ?parent_f_f_f_f_name . ?parent_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_name . ?parent_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . } ORDER BY DESC(?count) 第21世代 21世代まで遡ってみると、ワクシーという一頭に絞られてしまいました。ホエールボーンの父がワクシーです。 select distinct ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name (count(?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name) AS ?count) { { ?name prop-ja:wikiPageUsesTemplate template-ja:有馬記念勝ち馬. } ?name rdfs:label ?label ; prop-ja:父 ?parent_f_name . ?parent_f_name prop-ja:父 ?parent_f_f_name . ?parent_f_f_name prop-ja:父 ?parent_f_f_f_name . ?parent_f_f_f_name prop-ja:父 ?parent_f_f_f_f_name . ?parent_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_name . ?parent_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . } ORDER BY DESC(?count) 第22世代 このワクシーの親を調べようとしたら出てきませんでした。ホエールボーンの父が「ワクシー」なのですが、実際のWikipediaのページは「https://ja.wikipedia.org/wiki/ワキシー」となっています。「ワクシー」と「ワキシー」でURIが異なるためこれ以上辿れないのだと推測します。 select distinct ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name (count(?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name) AS ?count) { { ?name prop-ja:wikiPageUsesTemplate template-ja:有馬記念勝ち馬. } ?name rdfs:label ?label ; prop-ja:父 ?parent_f_name . ?parent_f_name prop-ja:父 ?parent_f_f_name . ?parent_f_f_name prop-ja:父 ?parent_f_f_f_name . ?parent_f_f_f_name prop-ja:父 ?parent_f_f_f_f_name . ?parent_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_name . ?parent_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name prop-ja:父 ?parent_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_f_name . } ORDER BY DESC(?count) 終わりに 次は英語版でやってみます。 今回は全て父を辿りましたが、他のプロパティを組み合わせて分析したいなと思いました。競馬の分析用途に自前のRDFストアを構築するということもやってみたいと思いました。 --- ### EC2上にWordPressをインストールする date: 2020-02-17 url: https://zatoima.github.io/wordpress-ec2-install.html tags: WordPress, AWS, EC2 はじめに 知人にIT業界にいるんだから、ホームページくらい作れるんでしょ?と煽られたのでWordPressをAWSのEC2上にインストールしていきます。 WordPressのインストール要件は下記の通り。 要件 | WordPress.org 日本語 https://ja.wordpress.org/about/requirements/ PHP バージョン 7.3 以上。 MySQL バージョン 5.6 以上、または MariaDB バージョン 10.1 以上 HTTPS 対応 環境情報 無料枠のt2.microにインストールしていきます。Amazon Linuxです。 [ec2-user@wp-ec2 ~]$ cat /etc/os-release NAME="Amazon Linux" VERSION="2" ID="amzn" ID_LIKE="centos rhel fedora" VERSION_ID="2" PRETTY_NAME="Amazon Linux 2" ANSI_COLOR="0;33" CPE_NAME="cpe:2.3:amazon:amazon_linux:2" HOME_URL="https://amazonlinux.com/" MySQL MySQLのインストール Amazon LinuxにはデフォルトでMariaDBがインストールされているので、MySQL5.7を使用できるように設定をしていきます。MariaDBで良い場合は特に何もしなくて良いかと思います。 sudo su - yum info mysql #リポジトリの追加 yum localinstall -y https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm #mysql8.0リポジトリの無効化 yum-config-manager --disable mysql80-community #mysql5.7リポジトリの有効化 yum-config-manager --enable mysql57-community #mysql5.7がインストールできるか確認 yum info mysql-community-server #インストール yum -y install mysql-community-server #バージョン確認 mysqld --version #自動起動確認 systemctl start mysqld.service systemctl enable mysqld.service systemctl status mysqld.service 参考:AWSのEC2で行うAmazon Linux2(MySQL5.7)環境構築 - Qiita https://qiita.com/2no553/items/952dbb8df9a228195189 MySQLの5.7.29がインストールされました。 [root@wp-ec2 ~]# mysqld --version mysqld Ver 5.7.29 for Linux on x86_64 (MySQL Community Server (GPL)) [root@wp-ec2 ~]# [root@wp-ec2 ~]# systemctl status mysqld.service ● mysqld.service - MySQL Server Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled) Active: active (running) since Sun 2020-02-02 02:54:44 UTC; 4s ago Docs: man:mysqld(8) http://dev.mysql.com/doc/refman/en/using-systemd.html Main PID: 3749 (mysqld) CGroup: /system.slice/mysqld.service └─3749 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid Feb 02 02:54:39 wp-ec2 systemd[1]: Starting MySQL Server... Feb 02 02:54:44 wp-ec2 systemd[1]: Started MySQL Server. [root@wp-ec2 ~]# mysqlの初期設定 cat /var/log/mysqld.log | grep password mysql_secure_installation Change the password for root ? ((Press y|Y for Yes, any other key for No) : no Remove anonymous users? (Press y|Y for Yes, any other key for No) : yes Disallow root login remotely? (Press y|Y for Yes, any other key for No) : yes Remove test database and access to it? (Press y|Y for Yes, any other key for No) : yes Reload privilege tables now? (Press y|Y for Yes, any other key for No) : yes 文字コード変更 mysql -u root -p show global variables like 'character%'; /etc/my.cnfの設定を変更 sudo vi /etc/my.cnf [mysqld] character_set_server=utf8mb4 [client] default-character-set=utf8mb4 mysqlを再起動 sudo systemctl restart mysqld.service WordPress用のデータベース、ユーザ設定を行う create database wp1; grant all privileges on `wp1`.* to 'wp1'@'localhost' IDENTIFIED BY 'xxxxxxxx'; show grants for wp1@localhost; SELECT host, user FROM mysql.user; PHP PHPのインストール amazon-linux-extras list | grep php amazon-linux-extras install php7.3 php -v バージョン確認 [root@wp-ec2 ~]# php -v PHP 7.3.11 (cli) (built: Oct 31 2019 19:16:47) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.3.11, Copyright (c) 1998-2018 Zend Technologies [root@wp-ec2 ~]# Apache Apacheのインストール [root@wp-ec2 ~]# yum info httpd Loaded plugins: extras_suggestions, langpacks, priorities, update-motd 31 packages excluded due to repository priority protections Available Packages Name : httpd Arch : x86_64 Version : 2.4.41 Release : 1.amzn2.0.1 Size : 1.3 M Repo : amzn2-core/2/x86_64 Summary : Apache HTTP Server URL : https://httpd.apache.org/ License : ASL 2.0 Description : The Apache HTTP Server is a powerful, efficient, and extensible : web server. yum -y install httpd [root@wp-ec2 ~]# httpd -v Server version: Apache/2.4.41 () Server built: Oct 22 2019 22:59:04 [root@wp-ec2 ~]# Apacheの起動 systemctl status httpd systemctl start httpd systemctl status httpd [root@wp-ec2 ~]# systemctl status httpd ● httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled) Drop-In: /usr/lib/systemd/system/httpd.service.d └─php-fpm.conf Active: inactive (dead) Docs: man:httpd.service(8) [root@wp-ec2 ~]# [root@wp-ec2 ~]# systemctl start httpd [root@wp-ec2 ~]# [root@wp-ec2 ~]# systemctl status httpd ● httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled) Drop-In: /usr/lib/systemd/system/httpd.service.d └─php-fpm.conf Active: active (running) since Sun 2020-02-02 03:13:17 UTC; 4s ago Docs: man:httpd.service(8) Main PID: 30339 (httpd) Status: "Processing requests..." CGroup: /system.slice/httpd.service ├─30339 /usr/sbin/httpd -DFOREGROUND ├─30346 /usr/sbin/httpd -DFOREGROUND ├─30347 /usr/sbin/httpd -DFOREGROUND ├─30348 /usr/sbin/httpd -DFOREGROUND ├─30349 /usr/sbin/httpd -DFOREGROUND └─30350 /usr/sbin/httpd -DFOREGROUND Feb 02 03:13:17 wp-ec2 systemd[1]: Starting The Apache HTTP Server... Feb 02 03:13:17 wp-ec2 httpd[30339]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::459:bdff:fe4b:3ffa. Set the 'ServerN... this message Feb 02 03:13:17 wp-ec2 systemd[1]: Started The Apache HTTP Server. Hint: Some lines were ellipsized, use -l to show in full. [root@wp-ec2 ~]# [root@wp-ec2 ~]# [root@wp-ec2 ~]# ps -ef | grep httpd | grep -v grep root 30339 1 0 03:13 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND apache 30346 30339 0 03:13 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND apache 30347 30339 0 03:13 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND apache 30348 30339 0 03:13 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND apache 30349 30339 0 03:13 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND apache 30350 30339 0 03:13 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND [root@wp-ec2 ~]# Apacheの起動設定確認 systemctl is-enabled httpd systemctl enable httpd systemctl is-enabled httpd [root@wp-ec2 ~]# systemctl is-enabled httpd disabled [root@wp-ec2 ~]# systemctl enable httpd Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service. [root@wp-ec2 ~]# [root@wp-ec2 ~]# systemctl is-enabled httpd enabled [root@wp-ec2 ~]# Apacheのインストール、及び有効化も完了したので、Webサーバへのテストアクセスを行う。ブラウザでパブリックIPを入力して移動する。現時点では特にコンテンツを配置していないので、Apacheのテストページが表示される。 ※AWS側のセキュリティグループの設定が必要。http(もしくはhttps)のプロトコルとポートを開けてください。 ファイルのパーミッション変更 Amazon Linux Apache ドキュメントルートは /var/www/htmlであり、デフォルトでは root によって所有されるのでこれをec2-userでも編集できるように変更する。具体的にはec2-user を apache グループに追加し、apache ディレクトリの所有権を /var/www グループに付与し、グループへの書き込み権限を割り当てる。これによりwordpressのファイル編集やphpファイルの編集が出来るようになる。 usermod -a -G apache ec2-user exit 再ログインして確認する。 [ec2-user@wp-ec2 ~]$ groups ec2-user adm wheel apache systemd-journal [ec2-user@wp-ec2 ~]$ /var/www とそのコンテンツのグループ所有権を apache グループに変更 sudo chown -R ec2-user:apache /var/www グループの書き込み許可を追加して、これからのサブディレクトにグループ ID を設定するには、/var/www とサブディレクトのディレクトリ許可を変更 sudo chmod 2775 /var/www && find /var/www -type d -exec sudo chmod 2775 {} \; グループ書き込み許可を追加するには、/var/www とサブディレクトリのファイル許可を再帰的に変更 sudo find /var/www -type f -exec sudo chmod 0664 {} \; httpd.confの修正 vi /etc/httpd/conf/httpd.conf AllowOverride NoneをAllowOverride Allに変更する。 WordPress WordPressのインストール、設定 SSL/TLSの設定は一旦、置いておいてWordPress環境のインストール、設定を行う。 wget https://ja.wordpress.org/latest-ja.tar.gz tar -xzf latest-ja.tar.gz wp-config.php ファイルの作成と編集 cp wordpress/wp-config-sample.php wordpress/wp-config.php vi wordpress/wp-config.php 下記情報を入力していく。 define('DB_NAME', 'wordpress-db'); define('DB_USER', 'wordpress-user'); define('DB_PASSWORD', 'your_strong_password'); 次にAuthentication Unique Keys and Salts のセクションを修正する。これらの KEY と SALT の値は、WordPress ユーザーがローカルマシンに保存したブラウザクッキーに対する暗号化レイヤーを提供します。基本的に、ここで長くてランダムな値を指定すると、サイトのセキュリティが向上します。 define( 'AUTH_KEY', 'put your unique phrase here' ); define( 'SECURE_AUTH_KEY', 'put your unique phrase here' ); define( 'LOGGED_IN_KEY', 'put your unique phrase here' ); define( 'NONCE_KEY', 'put your unique phrase here' ); define( 'AUTH_SALT', 'put your unique phrase here' ); define( 'SECURE_AUTH_SALT', 'put your unique phrase here' ); define( 'LOGGED_IN_SALT', 'put your unique phrase here' ); define( 'NONCE_SALT', 'put your unique phrase here' ); 下記にアクセスしてSALTのキーを取得して貼り付ける。 https://api.wordpress.org/secret-key/1.1/salt/ パーミッション変更 wordpress配下の所有者とgroupをapache所有とする sudo chown -R apache:apache /var/www/html/* WordPressの設定 下記にアクセスして、WordPressのインストール設定を入力する。xxx.xxx.xxx.xxxはEC2にアタッチしたElasitc IP。 http://xxx.xxx.xxx.xxx/wp1/wp-admin/install.php ここまででWordPressを稼働できるところまで来た。独自ドメインの設定とHTTPS化はまた別途。 --- ### 1つのEC2インスタンス上に複数のWordPressをホストする方法 date: 2020-02-13 url: https://zatoima.github.io/wordpress-ec2-multipul-host.html tags: WordPress, AWS, EC2 はじめに t2.microインスタンス上に複数WordPressをホストしたいと思ったことがあった。あまりネット上でググったところ情報が無かったのでメモしとおきます。 理由としては 各サイトPV数もなく重要度も高くなく負荷も高くないので、可能な限りt2.microの無料枠の中で運用したい WordPressごとにEC2インスタンス立てるのは費用の観点からよろしくない。(t2.microインスタンスといえど) 複数インスタンスの管理がめんどくさい です。 やり方 いくつか方法はありそうでした。 WordPress側のマルチサイト機能 Apache(Webサーバ)とDBを複数立てる ApacheのVirtualHost機能を使用 1. WordPress側のマルチサイト機能 1.のWordPress側のマルチサイト機能はサブディレクトリとサブドメイン形式しか選べず、「複数ドメインを一つのWordPress上で運用」するのは出来ないみたいです。(知らないだけかもしれない) サブディレクトリ形式 http://example.com/blog1/ http://example.com/blog2/ サブドメイン形式 http://blog1.example.com/ http://blog2.example.com/ 2.Apache(Webサーバ)とDBを複数立てる 2.はt2.microで運用する上で限られたリソース食いそうなので出来ればやりたくなかった。 当初は下記の通りApache自体を複数に分けてリッスンポートも分けて…とする必要があるのかな、と思っていたのですが、3.のVirtualHost機能を使えばアクセス先のURLごとに制御が可能でした。 3.ApacheのVirtualHost機能を使用 結果、3.のデータベース層とApacheのVirtualHost機能を使うこと出来ました。 設定方法 MySQL上にデータベースを追加する create database wp2; grant all privileges on `wp2`.* to 'wp2'@'localhost' IDENTIFIED BY 'xxxxxxxx'; show grants for wp2@localhost; SELECT host, user FROM mysql.user; Apacheのディレクトリを作成 mkdir -p /var/www/html1 Apacheのマルチサイト設定 vi /etc/httpd/conf/httpd.conf 下記設定を追加する。 ServerNameに記載しているexample1.comにアクセスした人は/var/www/html/のページが表示され、example2.comにアクセスした人は/var/www/html1/のページが表示されるようになります。なお、Apacheのバージョンは2.4です。 <VirtualHost *:80> DocumentRoot /var/www/html/ ServerName example1.com:80 </VirtualHost> <VirtualHost *:80> DocumentRoot /var/www/html1/ ServerName example2.com:80 </VirtualHost> 以降は通常のWordPressのインストールと同様なのでこちらの「WordPress」のインストールをご参照ください。 EC2上にWordPressをインストールする | my opinion is my own https://zatoima.github.io/wordpress-ec2-install.html 最後に ApacheとMySQLを共有しているので何かトラブルがあった場合は仲良く一緒に影響を受けてしまうので重要度が高まってきたら別インスタンスを立ててホストするなど検討が必要だと思います。 --- ### The installed version of lxml is too old to be used with openpyxl のエラー対応 date: 2020-02-13 url: https://zatoima.github.io/python-lxml-old-error.html tags: python lxmlが古いとエラー おそらくin2csvで内部的に使っていると推測 [ec2-user@bastin ~]$ aws dms describe-table-statistics --replication-task-arn $(aws dms describe-replication-tasks | jq -r '.ReplicationTasks[].ReplicationTaskArn') | jq '.TableStatistics' | in2csv -f json /home/ec2-user/.local/lib/python2.7/site-packages/openpyxl/xml/__init__.py:15: UserWarning: The installed version of lxml is too old to be used with openpyxl lxmlをアップグレードする [ec2-user@bastin ~]$ sudo pip install --upgrade lxml DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. A future version of pip will drop support for Python 2.7. More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support Collecting lxml Downloading lxml-4.5.1-cp27-cp27mu-manylinux1_x86_64.whl (5.5 MB) |████████████████████████████████| 5.5 MB 10.0 MB/s Installing collected packages: lxml Attempting uninstall: lxml Found existing installation: lxml 3.2.1 Uninstalling lxml-3.2.1: Successfully uninstalled lxml-3.2.1 Successfully installed lxml-4.5.1 --- ### EC2上でnetkeiba-scraperを使ってJRAのレース情報を取得 date: 2020-02-10 url: https://zatoima.github.io/ec2-netkeiba-scraper.html はじめに EC2上でnetkeiba-scraperを使ってレース情報を取得する。今回このツールを使いたかった理由は情報取得なのでrace.dbに格納するところまでをやります。 バージョン情報 [ec2-user@scraperv2 ~]$ cat /etc/os-release NAME="Amazon Linux" VERSION="2" ID="amzn" ID_LIKE="centos rhel fedora" VERSION_ID="2" PRETTY_NAME="Amazon Linux 2" ANSI_COLOR="0;33" CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2" HOME_URL="https://amazonlinux.com/" [ec2-user@scraperv2 ~]$ ec2-metadata -t instance-type: m5.large [ec2-user@scraperv2 ~]$ 事前準備 javaとgitのインストール sudo yum -y install java git javaはAmazon LinuxなこともあってオープンJDK完全互換のCorrettoがインストールされています。 sbtのインストール curl https://bintray.com/sbt/rpm/rpm | sudo tee /etc/yum.repos.d/bintray-sbt-rpm.repo sudo yum -y install sbt sbt Reference Manual — Linux への sbt のインストール https://www.scala-sbt.org/1.x/docs/ja/Installing-sbt-on-Linux.html scalaのインストール 公式サイトからダウンロード。 wget https://downloads.lightbend.com/scala/2.13.1/scala-2.13.1.rpm sudo rpm -ivh scala-2.13.1.rpm netkeiba-scraperのダウンロード、設定変更 git clone https://github.com/stockedge/netkeiba-scraper.git 設定変更 ./netkeiba-scraper/src/main/scala/netkeiba-scraper/Main.scalaの修正 http -> httpsに変更 ログインURLの変更 : driver.get(“https://regist.netkeiba.com/account/?pid=login") 収集期間の変更 デフォルトの10年の情報を収集しようとすると全体で数日、いや1週間近く掛かるので1年に変更 修正前 //過去10年分のURLを収集する RaceListScraper.scrape(period = 12 * 10) 修正後 //過去1年分のURLを収集する RaceListScraper.scrape(period = 12 * 1) ./netkeiba-scraper/build.sbtを下記の通り修正 libraryDependencies += "org.xerial" % "sqlite-jdbc" % "3.7.2" libraryDependencies += "joda-time" % "joda-time" % "2.3" libraryDependencies += "org.joda" % "joda-convert" % "1.6" libraryDependencies += "commons-io" % "commons-io" % "2.4" libraryDependencies += "nu.validator.htmlparser" % "htmlparser" % "1.4" libraryDependencies += "org.seleniumhq.selenium" % "selenium-java" % "2.41.0" libraryDependencies += "commons-lang" % "commons-lang" % "2.6" libraryDependencies += "org.scala-lang.modules" %% "scala-xml" % "1.0.6" libraryDependencies ++= Seq( "org.scalikejdbc" %% "scalikejdbc" % "2.5.2", "com.h2database" % "h2" % "1.4.196", "ch.qos.logback" % "logback-classic" % "1.2.3" ) 参照: scalikejdbc/scalikejdbc: A tidy SQL-based DB access library for Scala developers. This library naturally wraps JDBC APIs and provides you easy-to-use APIs. https://github.com/scalikejdbc/scalikejdbc Maven Repository: org.scala-lang.modules » scala-xml https://mvnrepository.com/artifact/org.scala-lang.modules/scala-xml_2.11 netkeiba-scraperの実行 cd /home/ec2-user/netkeiba-scraper sbt run collecturl レース結果が載っているURLを収集して「race_list.txt」に保存 sbt:netkeiba-scraper> run collecturl [info] Updating https://repo1.maven.org/maven2/org/scalikejdbc/scalikejdbc_2.12/2.5.2/scalikejdbc_2.12-2.5.2.pom 100.0% [##########] 3.0 KiB (6.5 KiB / s) https://repo1.maven.org/maven2/com/h2database/h2/1.4.196/h2-1.4.196.pom ~中略~ 8: collecting URLs from https://db.netkeiba.com/?pid=race_top&date=20190504 9: collecting URLs from https://db.netkeiba.com/?pid=race_top&date=20190406 10: collecting URLs from https://db.netkeiba.com/?pid=race_top&date=20190302 11: collecting URLs from https://db.netkeiba.com/?pid=race_top&date=20190202 [success] Total time: 163 s (02:43), completed Feb 10, 2020, 2:28:33 AM sbt:netkeiba-scraper> run scrapehtml レース結果のHTMLをスクレイピングしてhtmlフォルダに保存 ※稼働確認のためにrace_url.txtの中身を1行(1レース分)を対象にしました。 sbt:netkeiba-scraper> run scrapehtml [info] running Main scrapehtml WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by net.sourceforge.htmlunit.corejs.javascript.NativeArray (file:/tmp/sbt_e627d576/target/8fadc32b/11102a7b/htmlunit-core-js-2.13.jar) to field java.util.Arrays$LegacyMergeSort.userRequested WARNING: Please consider reporting this to the maintainers of net.sourceforge.htmlunit.corejs.javascript.NativeArray WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release 1:downloading https://db.netkeiba.com/race/202005010101 [success] Total time: 7 s, completed Feb 10, 2020, 2:33:39 AM sbt:netkeiba-scraper> ここまで完了するとhtmlフォルダにダウンロードしてきたhtmlファイルが格納されています。 [ec2-user@scraperv2 html]$ pwd /home/ec2-user/netkeiba-scraper/html [ec2-user@scraperv2 html]$ ls -l total 108 -rw-rw-r-- 1 ec2-user ec2-user 107109 Feb 10 02:33 202005010101.html [ec2-user@scraperv2 html]$ run extract HTMLからレース結果を抜き出しSQLiteに保存 sbt:netkeiba-scraper> run extract [info] running Main extract 02:35:20.126 [run-main-2] DEBUG scalikejdbc.ConnectionPool$ - Registered connection pool : ConnectionPool(url:jdbc:sqlite:race.db, user:null) using factory : <default> 02:35:20.130 [run-main-2] DEBUG scalikejdbc.ConnectionPool$ - Registered singleton connection pool : ConnectionPool(url:jdbc:sqlite:race.db, user:null) ~中略~ [success] Total time: 1 s, completed Feb 10, 2020, 2:35:20 AM race.dbに格納されるデータについて 作成されるrace.dbの中にTableは4つ存在していました。 feature payoff race_info race_result なお、sqlite_sequenceというテーブルもありますが、AUTOINCREMENTの情報を sqlite_sequence というテーブルで管理しているので上記の4つがメイン。 payoff race_info race_result --- ### tweepyのstatusオブジェクトに格納される情報一覧 date: 2020-02-02 url: https://zatoima.github.io/twitter-api-tweepy-status-list.html tags: Twitter, Python, Tweepy Twitter APIとPythonを使って自動化して遊んでいます。毎回ググるのもtweepyのstatusの中身を出力して確認するのも面倒なのでメモ。 前提条件 Twitter APIの使用申請を行い下記のkeyやtokenを取得していること Consumer_key Consumer_secret Access_token Access_secret 参考:Twitter API 登録 (アカウント申請方法) から承認されるまでの手順まとめ ※2019年8月時点の情報 - Qiita https://qiita.com/kngsym2018/items/2524d21455aac111cdee テスト import tweepy Consumer_key = 'xxxx' Consumer_secret = 'xxxxxx' Access_token = 'xxx-xxx' Access_secret = 'xxxxxx' auth=tweepy.OAuthHandler(Consumer_key,Consumer_secret) auth.set_access_token(Access_token,Access_secret) api=tweepy.API(auth) status = api.user_timeline(id='zatoima1')[0] print(status) 結果 代表的な情報はこちら。 status.text ツイート status.id ツイート固有のID status.in_reply_to_status_id リプライ先のツイートID status.retweet_count リツイート数 status.favorite_count いいねの数 status.user.name ユーザー名 status.user.screen_name スクリーンネーム(@zatoima1) status.user.friends_count フォロー数 status.user.followers_count フォロワー数 status.user.description 自己紹介 他にも色々あるので全量の出力を貼り付け。 Status(_api=<tweepy.api.API object at 0x00000240734C1E48>, _json={'created_at': 'Thu Jan 30 12:08:18 +0000 2020', 'id': 1222854043690647552, 'id_str': '1222854043690647552', 'text': '海外出張時に休日に移動して月曜日から現地みたいなことやるけど、法律的というか判例的には「移動の時なんて何してもええんやから休日移動には代休あげんくてもええよ」となってるんよな。中々のトラップ。ほとんどの会社は代休くれるやろうけど。', 'truncated': False, 'entities': {'hashtags': [], 'symbols': [], 'user_mentions': [], 'urls': []}, 'source': '<a href="http://twitter.com/download/iphone" rel="nofollow">Twitter for iPhone</a>', 'in_reply_to_status_id': None, 'in_reply_to_status_id_str': None, 'in_reply_to_user_id': None, 'in_reply_to_user_id_str': None, 'in_reply_to_screen_name': None, 'user': {'id': 1080276052721553408, 'id_str': '1080276052721553408', 'name': 'zato', 'screen_name': 'zatoima1', 'location': '日本 東京', 'description': '都内で働くインフラフラフラエンジニア/Oracle Database/MySQL/PostgreSQL/AWSが主戦場、もしくは興味があります。英語頑張りたい。どうでもいい呟きが多いです。家系ラーメン。Worked at Oracle. Working at AWS。my opinion is my own', 'url': None, 'entities': {'description': {'urls': []}}, 'protected': False, 'followers_count': 86, 'friends_count': 149, 'listed_count': 1, 'created_at': 'Wed Jan 02 01:34:16 +0000 2019', 'favourites_count': 960, 'utc_offset': None, 'time_zone': None, 'geo_enabled': True, 'verified': False, 'statuses_count': 388, 'lang': None, 'contributors_enabled': False, 'is_translator': False, 'is_translation_enabled': False, 'profile_background_color': 'F5F8FA', 'profile_background_image_url': None, 'profile_background_image_url_https': None, 'profile_background_tile': False, 'profile_image_url': 'http://pbs.twimg.com/profile_images/1147139264112517120/Z6NuA_Dn_normal.jpg', 'profile_image_url_https': 'https://pbs.twimg.com/profile_images/1147139264112517120/Z6NuA_Dn_normal.jpg', 'profile_link_color': '1DA1F2', 'profile_sidebar_border_color': 'C0DEED', 'profile_sidebar_fill_color': 'DDEEF6', 'profile_text_color': '333333', 'profile_use_background_image': True, 'has_extended_profile': True, 'default_profile': True, 'default_profile_image': False, 'can_media_tag': False, 'followed_by': False, 'following': False, 'follow_request_sent': False, 'notifications': False, 'translator_type': 'none'}, 'geo': None, 'coordinates': None, 'place': None, 'contributors': None, 'is_quote_status': False, 'retweet_count': 0, 'favorite_count': 0, 'favorited': False, 'retweeted': False, 'lang': 'ja'}, created_at=datetime.datetime(2020, 1, 30, 12, 8, 18), id=1222854043690647552, id_str='1222854043690647552', text='海外出張時に休日に移動して月曜日から現地みたいなことやるけど、法律的というか判例的には「移動の時なんて何してもええんやから休日移動には代休あげんくてもええよ」となってるんよな。中々のトラップ。ほとんどの会社は代休くれるやろうけど。', truncated=False, entities={'hashtags': [], 'symbols': [], 'user_mentions': [], 'urls': []}, source='Twitter for iPhone', source_url='http://twitter.com/download/iphone', in_reply_to_status_id=None, in_reply_to_status_id_str=None, in_reply_to_user_id=None, in_reply_to_user_id_str=None, in_reply_to_screen_name=None, author=User(_api=<tweepy.api.API object at 0x00000240734C1E48>, _json={'id': 1080276052721553408, 'id_str': '1080276052721553408', 'name': 'zato', 'screen_name': 'zatoima1', 'location': '日本 東京', 'description': '都内で働くインフラフラフラエンジニア/Oracle Database/MySQL/PostgreSQL/AWSが主戦場、もしくは興味があります。英語頑張りたい。どうでもいい呟きが多いです。家系ラーメン。Worked at Oracle. Working at AWS。my opinion is my own', 'url': None, 'entities': {'description': {'urls': []}}, 'protected': False, 'followers_count': 86, 'friends_count': 149, 'listed_count': 1, 'created_at': 'Wed Jan 02 01:34:16 +0000 2019', 'favourites_count': 960, 'utc_offset': None, 'time_zone': None, 'geo_enabled': True, 'verified': False, 'statuses_count': 388, 'lang': None, 'contributors_enabled': False, 'is_translator': False, 'is_translation_enabled': False, 'profile_background_color': 'F5F8FA', 'profile_background_image_url': None, 'profile_background_image_url_https': None, 'profile_background_tile': False, 'profile_image_url': 'http://pbs.twimg.com/profile_images/1147139264112517120/Z6NuA_Dn_normal.jpg', 'profile_image_url_https': 'https://pbs.twimg.com/profile_images/1147139264112517120/Z6NuA_Dn_normal.jpg', 'profile_link_color': '1DA1F2', 'profile_sidebar_border_color': 'C0DEED', 'profile_sidebar_fill_color': 'DDEEF6', 'profile_text_color': '333333', 'profile_use_background_image': True, 'has_extended_profile': True, 'default_profile': True, 'default_profile_image': False, 'can_media_tag': False, 'followed_by': False, 'following': False, 'follow_request_sent': False, 'notifications': False, 'translator_type': 'none'}, id=1080276052721553408, id_str='1080276052721553408', name='zato', screen_name='zatoima1', location='日本 東京', description='都内で働くインフラフラフラエンジニア/Oracle Database/MySQL/PostgreSQL/AWSが主戦場、もしくは興味があります。英語頑張りたい。どうでもいい呟きが多いです。家系ラーメン。Worked at Oracle. Working at AWS。my opinion is my own', url=None, entities={'description': {'urls': []}}, protected=False, followers_count=86, friends_count=149, listed_count=1, created_at=datetime.datetime(2019, 1, 2, 1, 34, 16), favourites_count=960, utc_offset=None, time_zone=None, geo_enabled=True, verified=False, statuses_count=388, lang=None, contributors_enabled=False, is_translator=False, is_translation_enabled=False, profile_background_color='F5F8FA', profile_background_image_url=None, profile_background_image_url_https=None, profile_background_tile=False, profile_image_url='http://pbs.twimg.com/profile_images/1147139264112517120/Z6NuA_Dn_normal.jpg', profile_image_url_https='https://pbs.twimg.com/profile_images/1147139264112517120/Z6NuA_Dn_normal.jpg', profile_link_color='1DA1F2', profile_sidebar_border_color='C0DEED', profile_sidebar_fill_color='DDEEF6', profile_text_color='333333', profile_use_background_image=True, has_extended_profile=True, default_profile=True, default_profile_image=False, can_media_tag=False, followed_by=False, following=False, follow_request_sent=False, notifications=False, translator_type='none'), user=User(_api=<tweepy.api.API object at 0x00000240734C1E48>, _json={'id': 1080276052721553408, 'id_str': '1080276052721553408', 'name': 'zato', 'screen_name': 'zatoima1', 'location': '日本 東京', 'description': '都内で働くインフラフラフラエンジニア/Oracle Database/MySQL/PostgreSQL/AWSが主戦場、もしくは興味があります。英語頑張りたい。どうでもいい呟きが多いです。家系ラーメン。Worked at Oracle. Working at AWS。my opinion is my own', 'url': None, 'entities': {'description': {'urls': []}}, 'protected': False, 'followers_count': 86, 'friends_count': 149, 'listed_count': 1, 'created_at': 'Wed Jan 02 01:34:16 +0000 2019', 'favourites_count': 960, 'utc_offset': None, 'time_zone': None, 'geo_enabled': True, 'verified': False, 'statuses_count': 388, 'lang': None, 'contributors_enabled': False, 'is_translator': False, 'is_translation_enabled': False, 'profile_background_color': 'F5F8FA', 'profile_background_image_url': None, 'profile_background_image_url_https': None, 'profile_background_tile': False, 'profile_image_url': 'http://pbs.twimg.com/profile_images/1147139264112517120/Z6NuA_Dn_normal.jpg', 'profile_image_url_https': 'https://pbs.twimg.com/profile_images/1147139264112517120/Z6NuA_Dn_normal.jpg', 'profile_link_color': '1DA1F2', 'profile_sidebar_border_color': 'C0DEED', 'profile_sidebar_fill_color': 'DDEEF6', 'profile_text_color': '333333', 'profile_use_background_image': True, 'has_extended_profile': True, 'default_profile': True, 'default_profile_image': False, 'can_media_tag': False, 'followed_by': False, 'following': False, 'follow_request_sent': False, 'notifications': False, 'translator_type': 'none'}, id=1080276052721553408, id_str='1080276052721553408', name='zato', screen_name='zatoima1', location='日本 東京', description='都内で働くインフラフラフラエンジニア/Oracle Database/MySQL/PostgreSQL/AWSが主戦場、もしくは興味があります。英語頑張りたい。どうでもいい呟きが多いです。家系ラーメン。Worked at Oracle. Working at AWS。my opinion is my own', url=None, entities={'description': {'urls': []}}, protected=False, followers_count=86, friends_count=149, listed_count=1, created_at=datetime.datetime(2019, 1, 2, 1, 34, 16), favourites_count=960, utc_offset=None, time_zone=None, geo_enabled=True, verified=False, statuses_count=388, lang=None, contributors_enabled=False, is_translator=False, is_translation_enabled=False, profile_background_color='F5F8FA', profile_background_image_url=None, profile_background_image_url_https=None, profile_background_tile=False, profile_image_url='http://pbs.twimg.com/profile_images/1147139264112517120/Z6NuA_Dn_normal.jpg', profile_image_url_https='https://pbs.twimg.com/profile_images/1147139264112517120/Z6NuA_Dn_normal.jpg', profile_link_color='1DA1F2', profile_sidebar_border_color='C0DEED', profile_sidebar_fill_color='DDEEF6', profile_text_color='333333', profile_use_background_image=True, has_extended_profile=True, default_profile=True, default_profile_image=False, can_media_tag=False, followed_by=False, following=False, follow_request_sent=False, notifications=False, translator_type='none'), geo=None, coordinates=None, place=None, contributors=None, is_quote_status=False, retweet_count=0, favorite_count=0, favorited=False, retweeted=False, lang='ja') --- ### PostgreSQLのpg_stat_statementsのインストール、設定方法 date: 2020-01-30 url: https://zatoima.github.io/postgresql-pg-stat-statements-install.html tags: PostgreSQL contrib拡張モジュールの中にpg_stat_statementsが含まれており、このモジュールをインストールし設定することで下記のようなSQLを特定することが出来る。Oracle Databaseのv$sqlのような使い方が出来る。 実行されたSQL 実行時間が長いSQL 実行回数が多いSQL キャッシュヒット率が低いSQL バージョン -bash-4.2$ psql psql (10.11) Type "help" for help. postgres=# select version(); version ---------------------------------------------------------------------------------------------------------- PostgreSQL 10.11 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39), 64-bit (1 row) 前提条件 postgresql-contribがインストールされていること -bash-4.2$ rpm -qa | grep contrib postgresql10-contrib-10.11-2PGDG.rhel7.x86_64 ライブラリの確認 -bash-4.2$ pg_config --libdir /usr/pgsql-10/lib -bash-4.2$ find /usr/pgsql-10/lib -name pg_stat_statements.so /usr/pgsql-10/lib/pg_stat_statements.so pg_stat_statementsの設定方法 前提条件としてpostgresql-contrib パッケージ(pg_stat_statementsモジュールの中に含まれる)がインストールされていることが必要。 vi /var/lib/pgsql/10/data/postgresql.conf 下記パラメータを修正する。 shared_preload_libraries = 'pg_stat_statements' pg_stat_statements.max = 1000 pg_stat_statements.track = top pg_stat_statements.save = on ※custom_variable_classesの設定は不要。9.2のバージョンまで必要だった。 各パラメータの説明は下記の通り。調整すべきはpg_stat_statements.maxで保存/格納するSQL数を増やす減らすのと、pg_stat_statements.trackで再帰的なSQLも含めて保存するかどうか。 パラメータ 説明 shared_preload_libraries サーバが稼働する時点で事前に読み込まれなければならない1つ以上の共有ライブラリを指定。今回の場合はpg_stat_statementsライブラリ(/usr/pgsql-10/lib/pg_stat_statements.so)を読みこむ必要があるのでpg_stat_statementsを指定。 pg_stat_statements.max デフォルトは1000のSQLが記録される。記録されるSQL文の最大数を指定する。これを超えて異なるSQL文を検出した場合は、最も実行回数の低いSQL文の情報が切り捨てられる。 pg_stat_statements.track どのSQL文をモジュールによって計測するかを制御 top:(直接クライアントによって発行された)最上層のSQL文を記録(デフォルト) all:(関数の中から呼び出された文などの)入れ子になった文も記録 none:文に関する統計情報収集を無効 pg_stat_statements.track_utility このモジュールがユーティリティコマンドを記録するかどうかを指定。 ユーティリティコマンドとは、 SELECT、INSERT、UPDATEおよびDELETE以外のすべて。 デフォルトはon。 この設定はスーパーユーザのみが変更可。 pg_stat_statements.save サーバを終了させる際に文の統計情報を保存するかどうかを指定。 offの場合、統計情報は終了時に保存されず、サーバ開始時に再読み込みもされない。 デフォルト値はon パラメータ設定後にはサーバ再起動が必要。 /usr/pgsql-10/bin/pg_ctl stop --pgdata=/var/lib/pgsql/10/data /usr/pgsql-10/bin/pg_ctl start --pgdata=/var/lib/pgsql/10/data pg_stat_statementsの有効化 postgres=> \dx List of installed extensions Name | Version | Schema | Description ---------+---------+------------+------------------------------ plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language (1 row) postgres=> CREATE EXTENSION pg_stat_statements; CREATE EXTENSION postgres=> \dx List of installed extensions Name | Version | Schema | Description --------------------+---------+------------+----------------------------------------------------------- pg_stat_statements | 1.6 | public | track execution statistics of all SQL statements executed plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language (2 rows) postgres=> pgtest=> SELECT * FROM pg_available_extensions WHERE name = 'pg_stat_statements'; name | default_version | installed_version | comment --------------------+-----------------+-------------------+----------------------------------------------------------- pg_stat_statements | 1.6 | 1.6 | track execution statistics of all SQL statements executed (1 row) パラメータ値の確認 select name, setting, unit from pg_settings where name like 'pg_stat_statements%'; postgres=> select name, setting, unit from pg_settings where name like 'pg_stat_statements%'; name | setting | unit ----------------------------------+---------+------ pg_stat_statements.max | 5000 | pg_stat_statements.save | on | pg_stat_statements.track | top | pg_stat_statements.track_utility | on | (4 rows) pg_stat_statementsを実際に使ってみる pg_stat_statements_reset()関数を使用してリセットする postgres=# SELECT pg_stat_statements_reset(); pg_stat_statements_reset -------------------------- pgbenchでサンプルクエリを実行 -bash-4.2$ pgbench -i postgres NOTICE: table "pgbench_history" does not exist, skipping NOTICE: table "pgbench_tellers" does not exist, skipping NOTICE: table "pgbench_accounts" does not exist, skipping NOTICE: table "pgbench_branches" does not exist, skipping creating tables... 100000 of 100000 tuples (100%) done (elapsed 0.10 s, remaining 0.00 s) vacuum... set primary keys... done. 結果確認 postgres=# SELECT query, calls, total_time, rows, 100.0 * shared_blks_hit / postgres-# nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent postgres-# FROM pg_stat_statements ORDER BY total_time DESC LIMIT 5; -[ RECORD 1 ]--------------------------------------------------- query | copy pgbench_accounts from stdin calls | 1 total_time | 107.231306 rows | 100000 hit_percent | 0.36452004860267314702 -[ RECORD 2 ]--------------------------------------------------- query | alter table pgbench_accounts add primary key (aid) calls | 1 total_time | 57.199683 rows | 0 hit_percent | 99.9425947187141217 -[ RECORD 3 ]--------------------------------------------------- query | vacuum analyze pgbench_accounts calls | 1 total_time | 41.366501 rows | 0 hit_percent | 99.9199679871948780 -[ RECORD 4 ]--------------------------------------------------- query | vacuum analyze pgbench_branches calls | 1 total_time | 13.070895 rows | 0 hit_percent | 93.0107526881720430 -[ RECORD 5 ]--------------------------------------------------- query | alter table pgbench_branches add primary key (bid) calls | 1 total_time | 1.957248 rows | 0 hit_percent | 86.6197183098591549 補足 RDSやAuroraの場合は、ライブラリやパラメータの設定は特に不要で、CREATE EXTENSION pg_stat_statements;を実行するだけで良い。 https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html > パフォーマンスメトリクス – pg_stat_statements モジュールは、デフォルトで shared_preload_libraries に含まれています。そのため、作成後すぐにインスタンスを再起動する必要はありません。ただし、この機能を使用する場合は、ステートメント CREATE EXTENSION pg_stat_statements; を実行する必要があります。また、詳細なデータを pg_stat_statements に追加できるように、track_io_timing はデフォルトで有効になっています。 --- ### Amazon Neptuneのインスタンス作成からデータロード、クエリ実行までやってみる date: 2020-01-28 url: https://zatoima.github.io/aws-neptune-create-instance-execute-query-try.html tags: AWS, Neptune, RDF, SPARQL はじめに AWSの完全マネージド型のグラフデータベースサービスであるNeptuneを触ってみようと思う。インスタンス作成からRDF形式のデータロード、及びSPARQLを使用して単純なクエリ発行までやってみる。 グラフデータベースとは?Amazon Neptuneとは?については別記事でまとめたい。 下記stepで実施する。 インスタンスの作成 IAMロール作成、ロールのNeptuneへのアタッチ、S3VPCエンドポイントの設定 S3からデータのロード RDF4J コンソール、HTTP REST エンドポイントを使用してロードしたデータの確認 前提条件 VPCやS3の事前作成 インスタンスの作成 「データベースの作成」を選択 「DB詳細の指定」を入力。 今回は現時点の最新のバージョンである「Neptune 1.0.2.1.R4」を指定。インスタンス作成後のMulti-AZへの変更は現段階では出来ないので必要に応じてこのタイミングで選択する。 続きを入力。 RDSやAuroraと同じような入力項目。 「データベースの作成」ボタンをクリック後に作成が始まるので少々待つ。 大体5分~10分くらいで作成は完了した。 「IAMロールとS3VPCエンドポイントの設定」 データロードのための下準備としてIAMロールとS3 VPCエンドポイントの設定を行う。 前提条件: IAM ロールと Amazon S3 アクセス - Amazon Neptune https://docs.aws.amazon.com/ja_jp/neptune/latest/userguide/bulk-load-tutorial-IAM.html IAMの画面から「ロールの作成」を選択 S3を選択 「AmazonS3ReadOnlyAccess」を選択してポリシーをアタッチする。 必要に応じて ロール名は「NeptuneLoadFromS3」とした。 作成したロールの画面に移動する。 「信頼関係」-「信頼関係の編集」へと移動して下記を上書きして貼り付ける。 { "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": [ "rds.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] } 「Amazon Neptune クラスターに IAM ロール」を追加する Neptuneのクラスタに移動して「IAMロールの管理」を選択。 先程作成したIAMロール(NeptuneLoadFromS3)を追加する。 S3 VPCエンドポイントを作成 S3からNeptuneにロードする際にVPCエンドポイントが必要なのでVPCエンドポイントを設定する。 エンドポイントの作成画面で「com.amazonaws.ap-northeast-1.s3」を選択する。(今回はTokyoリージョンなのでap-northeast-1だが、他リージョンの場合はリージョン名が異なる。) VPCやルートテーブルを指定する S3からNeptuneへのデータのロード ここまででS3からNeptuneへロードする準備が出来た。ロードするデータは http://rdf.geospecies.org のデータを使用することにする。rdfxml形式のRDFデータのサンプルをS3の所定のバケットにアップロード [ec2-user@bastin nep-tool]$ curl -O http://rdf.geospecies.org/geospecies.rdf.gz % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 100 8891k 100 8891k 0 0 3405k 0 0:00:02 0:00:02 --:--:-- 3404k [ec2-user@bastin nep-tool]$ [ec2-user@bastin nep-tool]$ ls -l geospecies.rdf.gz -rw-rw-r-- 1 ec2-user ec2-user 9105109 Jan 28 08:16 geospecies.rdf.gz [ec2-user@bastin nep-tool]$ aws s3 cp geospecies.rdf.gz s3://nep-s3-xxxx/ upload: ./geospecies.rdf.gz to s3://nep-s3-xxxx/geospecies.rdf.gz [ec2-user@bastin nep-tool]$ 下記コマンドでデータをロードする。エンドポイント、source、format、iamRoleArnを必要に応じて変更が必要。 RDFの場合のformatは他にもturtleやntriplesなども選択可能。 ロードデータ形式 - Amazon Neptune https://docs.aws.amazon.com/ja_jp/neptune/latest/userguide/bulk-load-tutorial-format.html curl -X POST \ -H 'Content-Type: application/json' \ https://neptest.xxxxxxxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/loader -d ' { "source" : "s3://nep-s3-xxxx/geospecies.rdf.gz", "format" : "rdfxml", "iamRoleArn" : "arn:aws:iam::xxxxxxxxx:role/NeptuneLoadFromS3", "region" : "ap-northeast-1", "failOnError" : "FALSE", "parallelism" : "HIGH" }' 実行後、下記が表示される。状況確認にloadIdが必要なので控えておく。 { "status" : "200 OK", "payload" : { "loadId" : "eff1268f-17ab-473a-b845-c2d91a317c01" } データロードのステータス確認。先程取得したloadIdを指定する curl -G 'https://neptest.xxxxxxxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/loader/eff1268f-17ab-473a-b845-c2d91a317c01' 進行中の出力 [ec2-user@bastin nep-tool]$ curl -G 'https://neptest.xxxxxxxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/loader/eff1268f-17ab-473a-b845-c2d91a317c01' { "status" : "200 OK", "payload" : { "feedCount" : [ { "LOAD_IN_PROGRESS" : 1 } ], "overallStatus" : { "fullUri" : "s3://nep-s3-xxxx/geospecies.rdf.gz", "runNumber" : 1, "retryNumber" : 0, "status" : "LOAD_IN_PROGRESS", "totalTimeSpent" : 148, "startTime" : 1580199498, "totalRecords" : 2130000, "totalDuplicates" : 0, "parsingErrors" : 0, "datatypeMismatchErrors" : 0, "insertErrors" : 0 } } } ロード完了の出力 [ec2-user@bastin nep-tool]$ curl -G 'https://neptest.xxxxxxxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/loader/eff1268f-17ab-473a-b845-c2d91a317c01' { "status" : "200 OK", "payload" : { "feedCount" : [ { "LOAD_COMPLETED" : 1 } ], "overallStatus" : { "fullUri" : "s3://nep-s3-xxxx/geospecies.rdf.gz", "runNumber" : 1, "retryNumber" : 0, "status" : "LOAD_COMPLETED", "totalTimeSpent" : 149, "startTime" : 1580199498, "totalRecords" : 2201532, "totalDuplicates" : 0, "parsingErrors" : 0, "datatypeMismatchErrors" : 0, "insertErrors" : 0 } } 各フィールドの説明は下記の通り。今回の例では「2,201,532」行のロードに「149」秒掛かっていることがわかる。 Neptune Loader Get-Status API - Amazon Neptune https://docs.aws.amazon.com/ja_jp/neptune/latest/userguide/load-api-reference-status.html フィールド 説明 fullUri ロードされる 1 つ以上のファイルの URI。形式: s3://bucket/key runNumber このロードまたはフィードの実行数。これは、ロードが再開されると増加します。 retryNumber このロードまたはフィードの再試行回数。これは、ローダーがフィードまたはロードを自動的に再試行するときに増加されます。 status ロードあるいはフィードの返されたステータス。LOAD_COMPLETED はロードが問題なく成功したことを示します。 totalTimeSpent ロードまたはフィードのデータの解析や挿入に費やした時間 (秒単位)。これには、ソースファイルのリストを取得するのに費やされた時間は含まれません。 totalRecords ロードされた、またはロードしようとした全レコード。 totalDuplicates 発生した重複レコードの数。 parsingErrors 発生した解析エラーの数。 datatypeMismatchErrors 指定されたデータとデータ型が一致しないレコードの数。 insertErrors エラーのために挿入できなかったレコードの数。 Neptuneへのクエリ発行 データロードまで出来たのでクエリを発行する。 HTTP REST エンドポイントを使用する場合 HTTP REST エンドポイントを使用して Neptune DB インスタンスに接続する - Amazon Neptune https://docs.aws.amazon.com/ja_jp/neptune/latest/userguide/access-graph-sparql-http-rest.html curl -X POST --data-binary 'query=select ?s ?p ?o where {?s ?p ?o} limit 10' https://neptest.xxxxxxxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/sparql 実行結果 [ec2-user@bastin nep-tool]$ curl -X POST --data-binary 'query=select ?s ?p ?o where {?s ?p ?o} limit 10' https://neptest.xxxxxxxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/sparql { "head" : { "vars" : [ "s", "p", "o" ] }, "results" : { "bindings" : [ { "s" : { "type" : "uri", "value" : "http://lod.geospecies.org/ses/uRtpv" }, "p" : { "type" : "uri", "value" : "http://rdf.geospecies.org/ont/geospecies#isUnexpectedIn" }, "o" : { "type" : "uri", "value" : "http://sws.geonames.org/5001836/" } ~省略~ RDF4J コンソールを使用する場合 RDF4J コンソールを使用して Neptune DB インスタンスに接続する - Amazon Neptune https://docs.aws.amazon.com/ja_jp/neptune/latest/userguide/access-graph-sparql-rdf4j-console.html RDF4J のサイトからRDF4J SDKをダウンロード 特定のEC2にダウンロードしたzipファイルをアップロードする。 [ec2-user@bastin nep-tool]$ ls -l total 104740 -rw-r--r-- 1 ec2-user ec2-user 98147430 Jan 25 06:16 eclipse-rdf4j-3.0.4-sdk.zip -rw-rw-r-- 1 ec2-user ec2-user 9105109 Jan 28 08:16 geospecies.rdf.gz zipファイルをunzip後に、bin配下に存在する console.shを実行する [ec2-user@bastin nep-tool]$ ./eclipse-rdf4j-3.0.4/bin/console.sh 08:37:35.639 [main] DEBUG org.eclipse.rdf4j.common.platform.PlatformFactory - os.name = linux 08:37:35.652 [main] DEBUG org.eclipse.rdf4j.common.platform.PlatformFactory - Detected Posix platform Connected to default data directory RDF4J Console 3.0.4+47737c0 3.0.4+47737c0 Type 'help' for help. > Neptune DB インスタンス に SPARQL リポジトリを作成。 create sparql 下記情報の入力を求められるので入力する。未確認だがリードレプリカを作った場合はここの「SPARQL クエリのエンドポイント」と「SPARQL 更新エンドポイント」をマスタとリードレプリカに分けるべきなのではないかと推測。 変数名 値 SPARQL クエリのエンドポイント https://your-neptune-endpoint:port/sparql SPARQL 更新エンドポイント https://your-neptune-endpoint:port/sparql ローカルリポジトリ ID [endpoint@localhost] neptune リポジトリタイトル [SPARQL エンドポイントリポジトリ @localhost] Neptune DB instance > create sparql Please specify values for the following variables: SPARQL query endpoint: https://neptest.xxxxxxxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/sparql SPARQL update endpoint: https://neptest.xxxxxxxxxxxx.ap-northeast-1.neptune.amazonaws.com:8182/sparql Local repository ID [endpoint@localhost]: neptune Repository title [SPARQL endpoint repository @localhost]: neptune Repository created Neptune インスタンスに接続する。接続後はプロンプトにローカルリポジトリ IDが表示される。 > open neptune Opened repository 'neptune' neptune> HTTP REST エンドポイントを使用して実行した場合と同様のクエリを実行してみる。 neptune> sparql select ?s ?p ?o where {?s ?p ?o} limit 10 Evaluating SPARQL query... +------------------------+------------------------+------------------------+ | s | p | o | +------------------------+------------------------+------------------------+ | <http://lod.geospecies.org/ses/zJIK4>| <http://rdf.geospecies.org/ont/geospecies#hasScientificNameAuthorship>| "(LeConte, 1866)"^^xsd:string| | <http://lod.geospecies.org/ses/zJIK4>| <http://rdf.geospecies.org/ont/geospecies#hasScientificName>| "Iphthiminus opacus (LeConte, 1866)"^^xsd:string| | <http://lod.geospecies.org/ses/zJIK4>| <http://rdf.geospecies.org/ont/geospecies#isExpectedIn>| <http://sws.geonames.org/6255149/>| | <http://lod.geospecies.org/ses/zJIK4>| <http://rdf.geospecies.org/ont/geospecies#isExpectedIn>| <http://sws.geonames.org/5279468/>| | <http://lod.geospecies.org/ses/zJIK4>| <http://rdf.geospecies.org/ont/geospecies#hasNomenclaturalCode>| <http://rdf.geospecies.org/ont/geospecies#NomenclaturalCode_ICZN>| | <http://lod.geospecies.org/ses/zJIK4>| <http://rdf.geospecies.org/ont/geospecies#isUnknownAboutIn>| <http://sws.geonames.org/4862182/>| | <http://lod.geospecies.org/ses/zJIK4>| <http://rdf.geospecies.org/ont/geospecies#isUnknownAboutIn>| <http://sws.geonames.org/5037779/>| | <http://lod.geospecies.org/ses/zJIK4>| <http://rdf.geospecies.org/ont/geospecies#isUnknownAboutIn>| <http://sws.geonames.org/5001836/>| | <http://lod.geospecies.org/ses/zJIK4>| <http://rdf.geospecies.org/ont/geospecies#isUnknownAboutIn>| <http://sws.geonames.org/2635167/>| | <http://lod.geospecies.org/ses/zJIK4>| <http://rdf.geospecies.org/ont/geospecies#hasSubfamilyName>| "Coelometopinae"^^xsd:string| +------------------------+------------------------+------------------------+ 10 result(s) (1268 ms) neptune> --- ### Pythonista 3を使ってiPhone上でpython実行環境を構築する date: 2020-01-25 url: https://zatoima.github.io/python-pythonista-3-insatll-setting.html tags: python, Pythonista 3 定期的に動作させたいわけではないけど、空いている時間にたまーに動かしてみたいpythonのコードがあった。動かしたいときにPCを使える環境であれば良いが常にそういう環境ではないので、出来れば常に持ち歩いているiPhone or iPadから実行できないかと思いPythonista 3を試してみた。 Pythonista 3はiOS上でpythonを実行するための有料アプリ。2020年1月時点では1,200円。 ‎Pythonista 3 https://apps.apple.com/jp/app/pythonista-3/id1085978097 公式ページはこちら。 Pythonista for iOS http://omz-software.com/pythonista/ numpy、matplotlib、requestsなどの人気のあるサードパーティモジュールから、iOS用にカスタマイズされたモジュールが使用可能。iPhoneのモーションセンサーデータ、写真ライブラリ、連絡先、アラーム、iOSクリップボードなどの情報にアクセスすることが出来る。 心配な点は継続アップデートがあるかどうか。(最終アップデートが2018年だった) とはいえ、iOS上で3rd partyモジュールをインストールしてptyhonコードを実行出来る環境は他には見つからなかったので選択肢はこれしかないのかな、という印象。 今回はStaSHをインストールしてpipインストール出来る環境を整え、tweepyを使ってTwitter API操作を行う。 StaSh インストール StaSh(Pythoni**sta Sh**ell)はPythonista 3上でpipなどのコマンド操作が出来るようになる拡張機能。Pythonを使う上でpipは必須機能とも言えるのでStaShも入れておくべき。 インストールはまずはコンソールを開き下記コマンドを実行する。このコマンドでは https://raw.githubusercontent.com/ywangd/stash/master/getstash.pyからgetstash.pyをダウンロードする。 import requests as r; exec(r.get('http://bit.ly/get-stash').text) ​ githubからlaunch_stash.pyがダウンロードされる。“Home directory to Start StaSh"とのこと。 アプリを再起動する。「Script Library」- 「This iPhone」に移動 launch_stash.pyが配置されているのでこのpythonファイルを実行する。 コンソール画面が起動。この画面でpipコマンドを実行。ここではTwitterAPIのラッパーであるtweepyをインストール。 pythonコードを実行する pipで必要なモジュールをインストール出来たので実行するpythonコードをコピペで作って実行してみる。なお、Google DriveやDropboxなどのストレージクラウドから読み込むことは出来ず、ローカルのファイルかiCloudのドライブとなる。 ソースコード 実行結果 無事に実行できた。これでスマホしか使えないタイミングでもpythonを実行できるのでQOLが向上すると思う。ゲームの自動化とかも出来るのかな? 更に詳細を知りたい場合はこちらからどうぞ。 Pythonista for iOS http://omz-software.com/pythonista/ --- ### PostgreSQLの稼働状況確認用SQL date: 2020-01-22 url: https://zatoima.github.io/postgresql-monitoring-sql.html tags: PostgreSQL DB稼働状況の監視と性能解析用のツールは数あれど、やはりSQLを使った状況確認の機会は多いので、PostgreSQLの稼働状況確認時に使用するSQLをまとめた。必要に応じてまた都度追加していきたい。 PostgreSQL 10.11のバージョンでSQLの確認を実施済。バージョンが上がるにつれて便利なシステムカタログが増えているので最新バージョンを触ってみたい。 バージョン postgres=# select version(); version ---------------------------------------------------------------------------------------------------------- PostgreSQL 10.11 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39), 64-bit (1 row) commit数/rollback数の確認 SELECT datname, xact_commit, xact_rollback FROM pg_stat_database; DB単位のキャッシュヒット率の確認 SELECT datname, round(blks_hit*100/(blks_hit+blks_read), 2) AS cache_hit_ratio FROM pg_stat_database WHERE blks_read > 0; TBL単位のキャッシュヒット率の確認 SELECT relname, round(heap_blks_hit*100/(heap_blks_hit+heap_blks_read), 2) AS cache_hit_ratio FROM pg_statio_user_tables WHERE heap_blks_read > 0 ORDER BY cache_hit_ratio; INDEX単位のキャッシュヒット率の確認 SELECT relname, indexrelname, round(idx_blks_hit*100/(idx_blks_hit+idx_blks_read), 2) AS cache_hit_ratio FROM pg_statio_user_indexes WHERE idx_blks_read > 0 ORDER BY cache_hit_ratio; 表スキャンあたりの読み取り行数の確認 SELECT relname, seq_scan, seq_tup_read, seq_tup_read/seq_scan AS tup_per_read FROM pg_stat_user_tables WHERE seq_scan > 0 ORDER BY tup_per_read DESC; HOT更新の比率の確認 SELECT relname, n_tup_upd, n_tup_hot_upd, round(n_tup_hot_upd*100/n_tup_upd, 2) AS hot_upd_ratio FROM pg_stat_user_tables WHERE n_tup_upd > 0 ORDER BY hot_upd_ratio; 稼働しているプロセスの確認 SELECT pid, datname, usename, state, backend_type FROM pg_stat_activity; 実行されているSQLの確認 SELECT pid, query_start, substr(query, 0, 50) FROM pg_stat_activity WHERE state='active' ORDER BY query_start; WALアーカイブの確認 select * from pg_stat_archiver; デットロック回数の確認 SELECT datname,deadlocks FROM pg_stat_database where datname = 'pgbench'; デットロック状況の確認 SELECT l.pid, l.granted, d.datname, l.locktype, relation, relation::regclass, transactionid, l.mode FROM pg_locks l LEFT JOIN pg_database d ON l.database = d.oid WHERE l.pid != pg_backend_pid() ORDER BY l.pid ; 長時間かかっている処理を確認 SELECT pid, state, wait_event, wait_event_type, (NOW() - xact_start)::INTERVAL(3) AS tx_duration, (NOW() - query_start)::INTERVAL(3) AS sql_duration, query FROM pg_stat_activity WHERE pid <> pg_backend_pid() ; チェックポイント SELECT checkpoints_timed, checkpoints_req, checkpoint_write_time, checkpoint_sync_time, buffers_checkpoint FROM pg_stat_bgwriter; VACUUM last_vacuum, last_autovacuum でVACUUM, 自動VACUUMがいつ実行されたか、n_dead_tupで不要なタプルが何行削除されたか SELECT relname,n_live_tup,n_dead_tup,last_autovacuum,autovacuum_count FROM pg_stat_user_tables; ANALYZE SELECT relname,last_analyze,last_autoanalyze,analyze_count,autoanalyze_count FROM pg_stat_user_tables; 一時ファイルの書き出し select datname,temp_files,temp_bytes from pg_stat_database; トータルの実行時間が長いSQL/実行回数が多いSQLを確認。pg_stat_statementsの事前設定が必要。 SELECT datname, SUBSTRING(query, 1, 40) AS query, calls, TRUNC( total_time::NUMERIC, 3 ) AS total_time FROM pg_stat_statements LEFT OUTER JOIN pg_database ON pg_stat_statements.dbid = pg_database.oid WHERE datname = 'pgbench' ORDER BY total_time DESC LIMIT 5 ; データベースのサイズを確認 select pg_size_pretty(pg_database_size('pgbench')); テーブルのサイズを確認 select pg_relation_size('pgbench'); テーブルとインデックスのサイズ合計を確認 select pg_total_relation_size('pgbench'); 各テーブルごとのサイズ/タプル数をチェックする SELECT pgn.nspname, relname, pg_size_pretty(relpages::bigint * 8 * 1024) AS size, CASE WHEN relkind = 't' THEN (SELECT pgd.relname FROM pg_class pgd WHERE pgd.reltoastrelid = pg.oid) WHEN nspname = 'pg_toast' AND relkind = 'i' THEN (SELECT pgt.relname FROM pg_class pgt WHERE SUBSTRING(pgt.relname FROM 10) = REPLACE(SUBSTRING(pg.relname FROM 10), '_index', '')) ELSE (SELECT pgc.relname FROM pg_class pgc WHERE pg.reltoastrelid = pgc.oid) END::varchar AS refrelname, CASE WHEN nspname = 'pg_toast' AND relkind = 'i' THEN (SELECT pgts.relname FROM pg_class pgts WHERE pgts.reltoastrelid = (SELECT pgt.oid FROM pg_class pgt WHERE SUBSTRING(pgt.relname FROM 10) = REPLACE(SUBSTRING(pg.relname FROM 10), '_index', ''))) END AS relidxrefrelname, relfilenode, relkind, reltuples::bigint, relpages FROM pg_class pg, pg_namespace pgn WHERE pg.relnamespace = pgn.oid AND pgn.nspname NOT IN ('information_schema', 'pg_catalog') ORDER BY relpages DESC; 各テーブルの行長を取得 select tablename, attname, avg_width from pg_stats; 各テーブル(列単位)の統計情報を確認(pg_statビューを使用) SELECT * FROM pg_stats WHERE tablename = 'xxxxxxx'; DMLごとの実行回数を取得 select relname, n_tup_ins as insert_cnt, n_tup_upd as update_cnt, n_tup_del as delete_cnt from pg_stat_user_tables; ディスクソートの実行回数を取得 select datname, temp_files, pg_size_pretty(temp_bytes) as temp_bytes, pg_size_pretty(round(temp_bytes/temp_files,2)) as temp_file_size from pg_stat_database where temp_files > 0; 大量の行を読み取っている表スキャンを確認 select relname, seq_scan, seq_tup_read,seq_tup_read/seq_scan as tup_per_read from pg_stat_user_tables where seq_scan > 0 order by tup_per_read desc; dead tupleが多いテーブルを確認 select relname, n_live_tup, n_dead_tup,round(n_dead_tup*100/(n_dead_tup+n_live_tup), 2) as dead_ratio,pg_size_pretty(pg_relation_size(relid)) from pg_stat_user_tables where n_live_tup > 0 order by dead_ratio desc; IOに関する情報取得 select * from pg_statio_all_tables; SQLの総実行回数、総実行時間を確認する(pg_stat_statements) select substr(query, 0, 160) as query, calls ,(total_time / 1000)::numeric(10,3) as total_time_sec ,(mean_time / 1000)::numeric(10,3) as avg_time_sec ,(min_time / 1000)::numeric(10,3) as min_time_sec ,(max_time / 1000)::numeric(10,3) as max_time_sec from pg_stat_statements order by total_time desc limit 10; vaccumの進捗状況を確認 select v.pid, v.datname, c.relname, v.phase, v.heap_blks_total, v.heap_blks_scanned, v.heap_blks_vacuumed, v.index_vacuum_count, v.max_dead_tuples, v.num_dead_tuples from pg_stat_progress_vacuum as v join pg_class as c on v.relid = c.relfilenode ; テーブルのoidを確認 select relid,relname from pg_stat_all_tables; アクセス頻度の多いテーブル select relname, coalesce(seq_tup_read,0)+coalesce(idx_tup_fetch,0)+ coalesce(n_tup_ins,0)+coalesce(n_tup_upd,0)+coalesce(n_tup_del,0) as total, coalesce(seq_tup_read,0)+coalesce(idx_tup_fetch,0) as select, coalesce(n_tup_ins,0) as insert, coalesce(n_tup_upd,0) as update, coalesce(n_tup_del,0) as delete from pg_stat_user_tables order by total desc; I/O回数&キャッシュヒット率 select *,(heap_blks_hit*100) / (heap_blks_read+heap_blks_hit) as ritu from pg_statio_all_tables where heap_blks_hit >= 1 order by ritu; インデックス毎のアクセスに関する統計情報を確認 select * from pg_stat_all_indexes; パラメータ一覧と反映タイミング SELECT name,setting,unit,context FROM pg_settings; internal:変更不可(構築時設定確認用) postmaster:サーバ起動時 sighup:設定ファイルの再読み込み backend:セッション確立時に決定 superuser:スーパユーザ権限で動的変更可能 user:一般ユーザで動的変更可能 参考: 稼動統計情報を活用しよう by Let’s Postgres PGECons 2018年度WG3活動報告書 性能トラブル調査編 [改訂新版]内部構造から学ぶPostgreSQL 設計・運用計画の鉄則 PostgreSQL徹底入門 第4版 参考資料ダウンロード(LPI-JAPAN OSS-DB) OSS-DB Exam Gold技術解説無料セミナー --- ### RDSのDBパラメータをワンライナーで取得 date: 2020-01-20 url: https://zatoima.github.io/aws-rds-oneliner-get.html tags: AWS, RDS RDSのパラメータグループの設定値をawscliを通じて取得する。下記のようなCSVを取得するイメージ。 "名前","値","許可された値","変更可能","送信元","適用タイプ","データ型","説明","ApplyMethod","MinimumEngineVersion" "application_name",,,true,"engine-default","dynamic","string","Sets the application name to be reported in statistics and logs.","pending-reboot", "archive_command","/etc/rds/dbbin/pgscripts/rds_wal_archive %p",,false,"system","dynamic","string","Sets the shell command that will be called to archive a WAL file.","pending-reboot", "archive_timeout","300","0-2147483647",false,"system","dynamic","integer","(s) Forces a switch to the next xlog file if a new file has not been started within N seconds.","pending-reboot", "array_nulls",,"0,1",true,"engine-default","dynamic","boolean","Enable input of NULL elements in arrays.","pending-reboot", ~中略~ jqのインストール [root@bastin ~]# yum -y install jq aws rds describe-db-parametersで実行 [root@bastin ~]# aws rds describe-db-parameters --db-parameter-group-name db-prm-postgres10 \ | jq -r '["名前","値","許可された値","変更可能","送信元","適用タイプ","データ型","説明","ApplyMethod","MinimumEngineVersion"], (.Parameters[] | [.ParameterName,.ParameterValue,.AllowedValues,.IsModifiable,.Source,.ApplyType,.DataType,.Description,.ApplyMethod,.MinimumEngineVersion]) | @csv' --- ### ブログにGithubのcontributions(通称:草)を表示する date: 2020-01-19 url: https://zatoima.github.io/blog-github-contributions-list.html tags: blog, Github トップページにgithubのcontributionsが表示するようにした。github pagesでこのブログを運用しているのでブログを書いた場合に、この草が生えてくるという仕組み。 モチベーションと単純なかっこよさからトップページにgithubのcontributionsが表示するようにした。github pagesでこのブログを運用しているのでブログを書いた場合に、草が生えてくるという仕組み。 こちらのツールを使いました。 GitHub の草状況を PNG 画像で返す heroku app をつくってみた - えいのうにっき https://blog.a-know.me/entry/2016/01/09/222210 1.) アクセス 下記にアクセスする Grass-Graph / Imaging your GitHub Contributions Graph https://grass-graph.appspot.com/ 2.) githubのidを入力する 3.) メタタグが生成されるのでメモする 4.) 画像をクリックした場合にgithubの自分のページに飛ぶようにタグを追加する。 <a href="https://github.com/zatoima" target="_blank"> <img src="https://grass-graph.appspot.com/images/zatoima.png"> </a> 5.) このタグをブログサービスの指定の箇所に貼り付ける。 トップページに貼り付けてみた。 --- ### 過去日付でGithubの草を生やす date: 2020-01-13 url: https://zatoima.github.io/blog-github-contributions-before-date.html tags: blog, Github はじめに このブログはGithub Pagesで運用していて、今年の目標が『ブログを定期的に更新してアウトプットする』ことなので可視化したいと考えていた。GithubにはContribution を可視化する通称『草』があるのでこれを使って可視化しようと考えた。 一方、Github Pagesを使い始める前に更新した記事も多いので更新した日をContributionに反映させたいと思い、過去日付でGithubの草を生やす方法を調べてみた。 方法 草が生える条件は下記の通り。commitやissue、pull requestが条件となる。特にソースコードの修正は不要でこれだけで偽造Contribution出来る。 https://help.github.com/en/github/setting-up-and-managing-your-github-profile/viewing-contributions-on-your-profile What counts as a contribution On your profile page, certain actions count as contributions: Committing to a repository’s default branch or gh-pages branch Opening an issue Proposing a pull request Submitting a pull request review 今回はAuthorDateを過去日付になるようにgit commitコマンドに--dateを指定することにした。その後はpushして終わり。 コマンド git commit --allow-empty -m "COMMIT" --date="Dec 29 23:59:59 2019 +0900" git push origin master 確認 git log --pretty=fuller commit d0d02bd117419f4aacc7d8f16e78f192ec8ce79d Author: Imazato <xxxxx.xxxxxx@gmail.com> AuthorDate: Sun Dec 29 23:59:59 2019 +0900 Commit: Imazato <xxxxx.xxxxxx@gmail.com> CommitDate: Wed Jan 8 17:46:25 2020 +0900 COMMIT 結果 記事から更新日付を引っ張ってきて、コマンドを実行することで過去日付でも草が生えた。草が生えていないと落ち着かない体を目指す。 --- ### RDS(Oracle)にData Pumpでインポートする date: 2020-01-08 url: https://zatoima.github.io/aws-rds-oracle-datapump-import.html tags: AWS, RDS, Oracle 注意事項の確認 まず始めにマニュアルを眺めてみる。データベース全体のインポートはサポートされておらず、スキーマ単位、テーブル単位でインポートを行う必要があるようだ。Amazon RDS for Oracle では、管理ユーザー SYS または SYSDBA へのアクセスは許可されていないため、full モードでインポートしたり、Oracle 管理のコンポーネントのスキーマをインポートしたりすると、Oracle データディレクトリが損傷し、データベースの安定性に影響を及ぼす可能性があります。とのこと。早くて便利なトランスポータブル表領域もサポートされていないことに注意。 Amazon RDS での Oracle へのデータのインポート - Amazon Relational Database Service https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Oracle.Procedural.Importing.html 特定のスキーマやオブジェクトをインポートするには、schema または table モードでインポートを実行します。 インポートするスキーマをアプリケーションに必要なスキーマに制限します。 full モードではインポートしないでください。 Amazon RDS for Oracle では、管理ユーザー SYS または SYSDBA へのアクセスは許可されていないため、full モードでインポートしたり、Oracle 管理のコンポーネントのスキーマをインポートしたりすると、Oracle データディレクトリが損傷し、データベースの安定性に影響を及ぼす可能性があります。 大量のデータをロードする場合は、ダンプファイルをターゲットの Amazon RDS for Oracle DB インスタンスに転送し、インスタンスの DB スナップショットを作成後、インポートをテストして、問題なく完了したことを確認します。データベースコンポーネントが無効の場合は、DB インスタンスを削除後、DB スナップショットから再作成します。復元された DB インスタンスには、DB スナップショットの作成時に DB インスタンス上でステージングされたダンプファイルがすべて含まれています。 Oracle Data Pump エクスポートパラメータ (TRANSPORT_TABLESPACES、TRANSPORTABLE、TRANSPORT_FULL_CHECK) を使用して作成されたダンプファイルはインポートしないでください。Amazon RDS for Oracle DB インスタンスでは、このようなダンプファイルのインポートはサポートされていません。 Data PumpのダンプファイルをRDS内の DATA_PUMP_DIR (ディレクトリ・オブジェクト)に転送するので、一時的にRDS内の必要とされるストレージ量が多く必要なので特に注意が必要。Storage Fullにならないように注意が必要。インポート後も自動的に削除されるわけではないため、必要に応じてUTL_FILE.FREMOVEを使用した削除が必要。 Data Pumpの手法 Data Pumpでインポートする場合は、下記2つの方法がある。 Oracle Data Pump と Amazon S3 バケットを使用したデータのインポート Oracle Data Pump とデータベースリンクを使用したデータのインポート S3バケットを経由したデータのインポートについて オプショングループを作成して既存のRDS(Oracle)にアタッチする オプショングループを選択 オプショングループの作成を行う 名前、説明、エンジン、メジャーエンジンのバージョンを選択する グループ作成後に、オプションを追加する 「oracle-s3-integration」をオプションとして選択する。「すぐに適用」を「はい」にする。 「データベースの設定」に「オプショングループ」の指定欄があるのでさきほど作成したオプショングループを指定する。 必要なポリシー、IAMロールを作成してRDSインスタンスにアタッチする。 Amazon S3 の統合 - Amazon Relational Database Service https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/oracle-s3-integration.html#oracle-s3-integration.preparing 表領域の拡張 ALTER tablespace USERS resize 30G; インポートするユーザに権限を付与 DROP USER "DPUSR" CASCADE; CREATE USER "DPUSR" identified BY "oracle"; ALTER USER "DPUSR" QUOTA UNLIMITED ON USERS; GRANT DBA to "DPUSR"; GRANT CREATE SESSION TO "DPUSR"; GRANT "RESOURCE" TO "DPUSR"; GRANT UNLIMITED TABLESPACE TO "DPUSR"; S3からData Pumpのダンプファイルの転送、及びインポート 事前にディレクトリオブジェクトを確認する。 set pages 2000 lin 2000 col filename for a30 col FILESIZE for 99999999999 alter session set nls_date_format='YYYY/MM/DD HH24:MI:SS'; select * from table (rdsadmin.rds_file_util.listdir(p_directory => 'BDUMP')); select * from table (rdsadmin.rds_file_util.listdir(p_directory => 'DATA_PUMP_DIR')); s3のバケットを指定してDATA_PUMP_DIRにダウンロードする。 select rdsadmin.rdsadmin_s3_tasks.download_from_s3(p_bucket_name => 'pluto-dev-s3-test', p_directory_name => 'DATA_PUMP_DIR') AS TASK_ID FROM DUAL; 必要に応じてログを確認する。rdsadmin.rdsadmin_s3_tasks.download_from_s3を実行したタイミングでタスクIDがコンソール上に出力されるのでそちらを確認して、rdsadmin.rds_file_util.read_text_fileの引数に指定する。 select text from table(rdsadmin.rds_file_util.read_text_file('BDUMP','dbtask-1574174424228-1248.log')); DATA_PUMP_DIR配下にdmpファイルが配置されていることが確認できる SQL> select * from table (rdsadmin.rds_file_util.listdir(p_directory => 'DATA_PUMP_DIR')); FILENAME TYPE FILESIZE MTIME ------------------------------ ---------- ------------ ------------------- datapump/ directory 4096 2019/12/06 01:02:22 datapump_meta.dmp file 8237056 2019/12/06 01:02:22 dbms_datapumpプロシージャを使用してインポートする DECLARE hdnl NUMBER; BEGIN hdnl := dbms_datapump.open (operation => 'IMPORT', job_mode => 'FULL', version => 'COMPATIBLE'); DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'import.log', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_log_file); DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'expdat.dmp', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_dump_file); DBMS_DATAPUMP.START_JOB(handle => hdnl); end; / データベースリンクを経由したデータのインポートについて データベースリンクを作成する。Data Pumpのダンプファイルを転送する転送元で実施する。 drop database link ora121; create database link ora121 connect to master identified by "Oracle2019%" using '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=ora121rds.xxxxxxxxxx.ap-northeast-1.rds.amazonaws.com)(PORT=1521))(CONNECT_DATA=(SID=ora121)))'; ダンプファイルを転送する。 BEGIN DBMS_FILE_TRANSFER.PUT_FILE( source_directory_object => 'DP_DIR', source_file_name => 'expdat.dmp', destination_directory_object => 'DATA_PUMP_DIR', destination_file_name => 'expdat.dmp', destination_database => 'ora121' ); END; / 転送されているか確認する。RDS側で確認。 set pages 2000 lin 2000 col filename for a30 col FILESIZE for 99999999999 alter session set nls_date_format='YYYY/MM/DD HH24:MI:SS'; select * from table (rdsadmin.rds_file_util.listdir(p_directory => 'BDUMP')); select * from table (rdsadmin.rds_file_util.listdir(p_directory => 'DATA_PUMP_DIR')); インポートする。 DECLARE hdnl NUMBER; BEGIN hdnl := DBMS_DATAPUMP.open( operation => 'IMPORT', job_mode => 'SCHEMA', job_name=>null); DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'expdat.dmp', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_dump_file); DBMS_DATAPUMP.add_file( handle => hdnl, filename => 'imp.log', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_log_file); DBMS_DATAPUMP.METADATA_FILTER(hdnl,'SCHEMA_EXPR','IN (''HR'')'); DBMS_DATAPUMP.start_job(hdnl); END; / 必要に応じてログを確認する SELECT TEXT FROM TABLE(RDSADMIN.RDS_FILE_UTIL.READ_TEXT_FILE('DATA_PUMP_DIR','imp.log')); ログの削除方法 EXEC UTL_FILE.FREMOVE('DATA_PUMP_DIR','imp.log'); dbms_datapumpプロシージャを使用してインポートする DECLARE hdnl NUMBER; BEGIN hdnl := dbms_datapump.open (operation => 'IMPORT', job_mode => 'FULL', version => 'COMPATIBLE'); DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'import.log', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_log_file); DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'expdat.dmp', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_dump_file); DBMS_DATAPUMP.START_JOB(handle => hdnl); end; / その他 下記にはPerlスクリプトを使って、DATA_PUMP_DIRに転送する方法がある。 Strategies for Migrating Oracle Databases to AWS ​ Data Migration Using Oracle Data Pump - Next Steps for a Database on Amazon RDS [AWS] Data Pump のダンプファイルをRDS for Oracle インスタンスへ転送する | Developers.IO https://dev.classmethod.jp/cloud/aws/transfer-data-pump-file-to-rds-instace/ --- ### PostgreSQLのログ分析ツール pgBadgerを試す date: 2020-01-07 url: https://zatoima.github.io/postgresql-pgBadger-test.html tags: PostgreSQL はじめに pgBadgerはPostgreSQLのログファイルを解析しレポートを出力するツール。このツールはログを基に分析を行うが、SQL、待機イベント、IO統計、エラー統計、SQLヒストグラム、ロック、Vaccum統計などを多くのワークロードが確認できる。 まず始めにサンプルのレポートを見たい場合はこちら。予想していたよりもグラフィカルに確認できた。 Githubのリポジトリとreadmeはこちら。 darold/pgbadger: A fast PostgreSQL Log Analyzer https://github.com/darold/pgbadger pgBadgerをEC2インストールすればログを静的に解析できるという点でRDSやAuroraのPostgreSQL互換を対象に実行できるようなので確認してみる。(なお、pgbadgerの実行はEC2上にインストールしたPostgreSQL10.11で実行) ネイティブツールと外部ツールに基づいた Amazon RDS PostgreSQL のクエリの最適化とチューニング | Amazon Web Services ブログ https://aws.amazon.com/jp/blogs/news/optimizing-and-tuning-queries-in-amazon-rds-postgresql-based-on-native-and-external-tools/ pgBadgerの設定とpostgres.confの設定 インストール [ec2-user@postdb ~]$ sudo yum install pgbadger [ec2-user@postdb ~]$ which pgbadger /usr/bin/pgbadger [ec2-user@postdb ~]$ postgres.conf ログに関するパラメータを修正する。デフォルトより多くの情報を出すことになるので注意。 log_filename = 'postgresql-%Y-%m-%d.log' #指定時間以上のクエリのテキストと実行時間をログに残す。0の場合すべてのクエリが対象になる絞りたい場合は要調整 log_min_duration_statement = 0 log_line_prefix = '%t [%p]: [%l-1] user=%u, db=%d' # チェックポイントの実行のlogging log_checkpoints = on # クライアントの接続のlogging log_connections = on # クライアントの切断のlogging log_disconnections = on # deadlock_timeout で指定した時間(デフォルト1秒)以上のロック待ちをログに残す log_lock_waits = on #指定したサイズ以上の一時ファイルが作成された場合ログに記録 log_temp_files = 0 lc_messages = 'C' log_autovacuum_min_duration = 0 log_error_verbosity = default 実行コマンド /usr/bin/pgbadger -f '%t [%p]: [%l-1] user=%u, db=%d' -I -q /var/lib/pgsql/10/data/log/postgresql-2019-12-30.log -O /var/lib/pgsql/pgbadger/ 取得できる情報 時間帯別統計や待機が多いSQLクエリ、実行回数の多いクエリ、平均実行時間が長いクエリランキングなどが確認できる。サンプルのレポートを見たい場合はこちら。 https://github.com/darold/pgbadger#FEATURE その他の機能 自動増分レポートモード(incrementalオプションを指定してcron実行) 月次レポート 並列処理 --- ### 2020年にやってみたいこと date: 2020-01-01 url: https://zatoima.github.io/personal-goal-2020.html tags: Personal 2019年は転職とブログの継続という2つの大きな目標は達成できた。次は2020年に向けて元旦に整理してみた。 目標 今年は状況のアップデートや定期的に振り返りがしやすいようにtrelloで目標(ほぼやってみたいこと)を整理。目標の数は切りよく50個。一つ一つをもう少し定量的にして毎月振り返りを行いたい。(今年こそは・・・) 一覧 重点目標は健康管理とPersonal系。 List Title Labels Personal 映画:1本/月 On Going Personal ブログ:10記事/月以上 On Going Personal Duoをシャドーイング含めて完璧にする Needs work/review Personal 英語の勉強を継続する Needs work/review Personal Alexaの追加のスキル開発 Needs work/review Personal 情報系大学/大学院について調べてみる Needs work/review Personal 冷蔵庫の在庫管理(Raspberry Pi) Needs work/review Personal 料理本を基に料理をしてみる Needs work/review Personal 読書:1冊/月 Needs work/review Personal ブログ:100pv/月 Needs work/review Personal Advent Calendarに3つエントリーする Needs work/review Personal リポジトリを作ってリリースしてみる Needs work/review Personal webサービスかbotを作る Needs work/review Work OSS-DB Goldを取得 On Going Work AWS 認定ソリューションアーキテクト – プロフェッショナルを取得 Needs work/review Work 職務経歴書を定期的にアップデートしてキャリアの棚卸しを行う Needs work/review Work Tech Summit系のイベントに参加する Needs work/review Work 技術書:3冊/月 Needs work/review Work データベース以外の技術の軸を作る Needs work/review Work コンテナ(Docker/Kubernetes )の基礎知識を勉強する Needs work/review Work 機械学習やAIなどの習得に向けて勉強する Needs work/review Family/Social 新しいお店を 1件/月 新規開拓する On Going Family/Social 年に1回以上二人で一緒に実家に顔を出す On Going Family/Social モデルルーム見学に5件以上見に行く On Going Family/Social レコーダーを新調する On Going Family/Social テレビを新調する On Going Family/Social 実家に猫の観察システムを導入してみる Needs work/review Family/Social お盆に実家に帰る Needs work/review Health 体重で1年で-10kgを達成(BMI18.5〜25未満) On Going Health 健康診断でA評価に戻す On Going Health ラーメンの回数を2回/月にする On Going Health 筋トレ On Going Travel/Place ディズニーランド ホテルに泊まる On Going Travel/Place GWの旅行 On Going Travel/Place 愛媛旅行 Needs work/review Travel/Place 夏季休暇旅行 Needs work/review Travel/Place 温泉:星野リゾート Needs work/review Travel/Place ディズニーオンクラシックに行く Needs work/review Travel/Place ひまわり畑 Needs work/review Travel/Place 府中競馬場に競馬を見に行く Needs work/review Travel/Place Vリーグの男子を見に行く Impossible Financial 貯金:○○万円/月 On Going Financial 投資:○万円/月 On Going Financial ボーナス:○○○万円/年 On Going Financial 合計:○○○万円/年 On Going Financial ふるさと納税を毎月実施する On Going Financial 保険の見直し Needs work/review --- ### PostgreSQLのLogical Decodingについて date: 2019-12-29 url: https://zatoima.github.io/postgresql-logical-decoding.html tags: PostgreSQL はじめに Logical DecodingでWALに記録されたデータベースに対するアクティビティの履歴情報を抽出、参照することが出来る。Oracle DatabaseでいうところのLogMinerに近い機能と理解。機能としてはlogminerの方が細かい内容を確認出来る。PostgreSQLではDDLの内容まではLogical Decodingの対象とできないようだ。PostgreSQL9.4から実装されたLogical Decoding機能なのでこれからに期待。 なお、論理レプリケーションで使われるCDCも本機能を基に実装されている。 マニュアルはこちら。 https://www.postgresql.jp/document/10/html/logicaldecoding.htm 第48章 ロジカルデコーディング 設定方法 postgresql.confを変更 wal_levelを「logical」にmax_replication_slotsを「1」以上に変更する。PostgreSQL10の場合は、max_replication_slotsはデフォルト10となっているので特に変更の必要はない。wal_levelをデフォルトからlogicalに変更すると当然WALの生成量が増える。wal_levelを変更するので再起動が必要。 #postgresql.conf wal_level = logical max_replication_slots = 10 プラグインのインストール Logical Decodingのプラグインによって出力形式が異なる。decodeのpluginの一覧は下記のURLに記載がある。 https://wiki.postgresql.org/wiki/Logical_Decoding_Plugins Logical Decoding Plugins ここでは、contribの中に最初から含まれているtest_decodingと追加のインストールは必要だが、SQL Formatベースのdecoder_rawをインストールしたい。 test_decodingプラグインのインストール ソースのルートにcontribディレクトリがあるのでそこからmake installでインストールする。 $ cd contrib/test_decoding $ make # make insatll もしくはyumでインストールする。rpmなdのパッケージでインストールしている場合はこっち。 sudo yum install postgresql10-contrib decoder_rawプラグインのインストール githubからcloneしてmake installでインストールする。 https://github.com/michaelpq/pg_plugins/tree/master/decoder_raw [root@postdb tmp]# pwd /tmp [root@postdb tmp]# git clone https://github.com/michaelpq/pg_plugins.git Cloning into 'pg_plugins'... remote: Enumerating objects: 105, done. remote: Counting objects: 100% (105/105), done. remote: Compressing objects: 100% (50/50), done. remote: Total 1760 (delta 54), reused 90 (delta 47), pack-reused 1655 Receiving objects: 100% (1760/1760), 345.58 KiB | 716.00 KiB/s, done. Resolving deltas: 100% (1125/1125), done. [root@postdb tmp]# cd /tmp/pg_plugins/decoder_raw [root@postdb decoder_raw]# [root@postdb decoder_raw]# export PATH=$PATH:/usr/pgsql-10/bin [root@postdb decoder_raw]# make install gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC -I. -I./ -I/usr/pgsql-10/include/server -I/usr/pgsql-10/include/internal -D_GNU_SOURCE -I/usr/include/libxml2 -I/usr/include -c -o decoder_raw.o decoder_raw.c gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC -L/usr/pgsql-10/lib -Wl,--as-needed -L/usr/lib64 -Wl,--as-needed -Wl,-rpath,'/usr/pgsql-10/lib',--enable-new-dtags -shared -o decoder_raw.so decoder_raw.o /bin/mkdir -p '/usr/pgsql-10/lib' /bin/install -c -m 755 decoder_raw.so '/usr/pgsql-10/lib/' [root@postdb decoder_raw]# [root@postdb decoder_raw]# echo $? 0 [root@postdb decoder_raw]# makeインストール後には/usr/pgsql-10/lib配下に関連するライブラリが配置されている。 -bash-4.2$ pwd /usr/pgsql-10/lib -bash-4.2$ ls -l decoder_raw* -rwxr-xr-x 1 root root 75304 Dec 28 11:16 decoder_raw.so -bash-4.2$ ロジカルデコーディング関連の関数 関連する関数は多くはない。この3つで十分なはず。 pg_create_logical_replication_slot pg_create_logical_replication_slot(slot_name name, plugin name [, temporary boolean]) 論理(デコード)レプリケーションスロットを作成する。 第1引数:slot_name を指定 第2引数:plugin name を指定 第3引数:trueに設定するとそのスロットは現行セッションに限定される(オプション) pg_drop_replication_slot pg_drop_replication_slot(slot_name name) 論理(デコード)レプリケーションスロットを削除する。 第1引数:slot_name を指定 pg_logical_slot_get_changes pg_logical_slot_get_changes(slot_name name, upto_lsn pg_lsn, upto_nchanges int, VARIADIC options text[]) 変更履歴を確認する 第1引数:slot_name を指定 第2引数:確認するLSN を指定 第3引数:何行分出力するか 第4引数:出力プラグインのオプションをkeyとvalueで指定 1.) ロジカルデコーディングを行ってみる(test_decodingプラグインを使用) レプリケーションスロットの作成 ロジカルデコーディングを行いたいデータベースでpg_create_logical_replication_slotを実行してレプリケーション・スロットを作成する。 postgres=# SELECT * FROM pg_create_logical_replication_slot('decodeslot1', 'test_decoding'); slot_name | lsn -------------+----------- decodeslot1 | 0/2EFFFA0 (1 row) postgres=# \x Expanded display is on. postgres=# postgres=# SELECT slot_name, plugin, slot_type, database, active, restart_lsn, confirmed_flush_lsn FROM pg_replication_slots; -[ RECORD 1 ]-------+-------------- slot_name | decodeslot1 plugin | test_decoding slot_type | logical database | postgres active | f restart_lsn | 0/2EFFF68 confirmed_flush_lsn | 0/2EFFFA0 変更履歴を確認 当然現時点では特に操作を行っていないので何も出力されない。 postgres=# SELECT * FROM pg_logical_slot_get_changes('decodeslot1', NULL, NULL); (0 rows) テーブルに対してDDLを行ってみる DDLでは特に内容は出力されない。BEGINとCOMMITは出力される。 postgres=# CREATE TABLE data(id serial primary key, data text); CREATE TABLE postgres=# SELECT * FROM pg_logical_slot_get_changes('decodeslot1', NULL, NULL); lsn | xid | data -----------+------+------------- 0/2F20128 | 1051 | BEGIN 1051 0/2F28278 | 1051 | COMMIT 1051 (4 rows) テーブルに対してDMLを行ってみる postgres=# BEGIN; BEGIN postgres=# INSERT INTO data(data) VALUES('1'); INSERT 0 1 postgres=# INSERT INTO data(data) VALUES('2'); INSERT 0 1 postgres=# COMMIT; COMMIT postgres=# postgres=# SELECT * FROM pg_logical_slot_get_changes('decodeslot1', NULL, NULL); lsn | xid | data -----------+------+--------------------------------------------------------- 0/2F282F0 | 1052 | BEGIN 1052 0/2F28358 | 1052 | table public.data: INSERT: id[integer]:1 data[text]:'1' 0/2F28460 | 1052 | table public.data: INSERT: id[integer]:2 data[text]:'2' 0/2F28510 | 1052 | COMMIT 1052 (4 rows) postgres=# postgres=# postgres=# INSERT INTO data(data) VALUES('3'); INSERT 0 1 postgres=# postgres=# SELECT * FROM pg_logical_slot_peek_changes('decodeslot1', NULL, NULL); lsn | xid | data -----------+------+--------------------------------------------------------- 0/2F28588 | 1053 | BEGIN 1053 0/2F28588 | 1053 | table public.data: INSERT: id[integer]:3 data[text]:'3' 0/2F28638 | 1053 | COMMIT 1053 (3 rows) レプリケーションスロットを削除 SELECT * FROM pg_drop_replication_slot('decodeslot1'); 2.) ロジカルデコーディングを行ってみる(decoder_rawプラグインを使用) ロジカルデコーディングを行いたいデータベースでpg_create_logical_replication_slotを実行してレプリケーション・スロットを作成する。 レプリケーションスロットの作成 postgres=# SELECT * FROM pg_create_logical_replication_slot('decodeslot1', 'decoder_raw'); slot_name | lsn -------------+----------- decodeslot1 | 0/2F286A8 (1 row) postgres=# \x Expanded display is on. postgres=# SELECT slot_name, plugin, slot_type, database, active, restart_lsn, confirmed_flush_lsn FROM pg_replication_slots; -[ RECORD 1 ]-------+------------ slot_name | decodeslot1 plugin | decoder_raw slot_type | logical database | postgres active | f restart_lsn | 0/2F28670 confirmed_flush_lsn | 0/2F286A8 変更履歴を確認 当然現時点では特に操作を行っていないので何も出力されない。 postgres=# SELECT * FROM pg_logical_slot_get_changes('decodeslot1', NULL, NULL); lsn | xid | data -----+-----+------ (0 rows) テーブルに対してDDLを行ってみる DDLでは特に内容は出力されない。test_decodingと異なりBEGINとCOMMITも出力されない。 postgres=# CREATE TABLE data(id serial primary key, data text); CREATE TABLE postgres=# SELECT * FROM pg_logical_slot_get_changes('decodeslot1', NULL, NULL); lsn | xid | data -----+-----+------ (0 rows) テーブルに対してDMLを行ってみる postgres=# BEGIN; BEGIN postgres=# INSERT INTO data(data) VALUES('1'); INSERT 0 1 postgres=# INSERT INTO data(data) VALUES('2'); INSERT 0 1 postgres=# COMMIT; COMMIT postgres=# SELECT * FROM pg_logical_slot_get_changes('decodeslot1', NULL, NULL); lsn | xid | data -----------+------+----------------------------------------------------- 0/2F554B0 | 1058 | INSERT INTO public.data (id, data) VALUES (1, '1'); 0/2F55580 | 1058 | INSERT INTO public.data (id, data) VALUES (2, '2'); (2 rows) postgres=# INSERT INTO data(data) VALUES('3'); INSERT 0 1 postgres=# SELECT * FROM pg_logical_slot_peek_changes('decodeslot1', NULL, NULL); lsn | xid | data -----------+------+----------------------------------------------------- 0/2F55630 | 1059 | INSERT INTO public.data (id, data) VALUES (3, '3'); (1 row) レプリケーションスロットを削除 SELECT * FROM pg_drop_replication_slot('decodeslot1'); --- ### EC2(Amazon Linux2)にPostgreSQLをインストールする date: 2019-12-28 url: https://zatoima.github.io/postgresql-ec2-insatll.html tags: PostgreSQL, EC2, AWS Amazon LinuxにRed hat用のリポジトリからyumでインストールしようとするとエラーになるので無理やりAmazon Linux2でYumでインストールしようという内容。 ちなみに、PostgreSQLのコミュニティでは下記がYumで利用可能なプラットフォームとされていますのでご注意ください。 PostgreSQL RPM Repository (with Yum) https://yum.postgresql.org/ Available Platforms Red Hat Enterprise Linux/CentOS/Oracle Enterprise Linux 8 Red Hat Enterprise Linux/CentOS/Oracle Enterprise Linux/Scientific Linux 7 Red Hat Enterprise Linux/CentOS/Oracle Enterprise Linux/Scientific Linux 6 SuSE Enterprise Linux 12 SP5 Fedora 32 Fedora 31 Fedora 30 デフォルトで参照しているAmazon Linuxのリポジトリは古いので、リポジトリをlocalにinsatllする。ただ、Amazon Linuxにredhat用のリポジトリをyumでインストールしようとするとエラーになる。 Error: Package: pgdg-redhat-repo-42.0-5.noarch (/pgdg-redhat-repo-latest.noarch) Requires: /etc/redhat-release [ec2-user@postdb ~]$ sudo yum -y localinstall https://download.postgresql.org/pub/repos/yum/10/redhat/rhel-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm Loaded plugins: extras_suggestions, langpacks, priorities, update-motd pgdg-redhat-repo-latest.noarch.rpm | 5.8 kB 00:00:00 Examining /var/tmp/yum-root-Ie6yep/pgdg-redhat-repo-latest.noarch.rpm: pgdg-redhat-repo-42.0-5.noarch Marking /var/tmp/yum-root-Ie6yep/pgdg-redhat-repo-latest.noarch.rpm to be installed Resolving Dependencies --> Running transaction check ---> Package pgdg-redhat-repo.noarch 0:42.0-5 will be installed --> Processing Dependency: /etc/redhat-release for package: pgdg-redhat-repo-42.0-5.noarch --> Processing Dependency: /etc/redhat-release for package: pgdg-redhat-repo-42.0-5.noarch --> Finished Dependency Resolution Error: Package: pgdg-redhat-repo-42.0-5.noarch (/pgdg-redhat-repo-latest.noarch) Requires: /etc/redhat-release You could try using --skip-broken to work around the problem You could try running: rpm -Va --nofiles --nodigest [ec2-user@postdb ~]$ Amazon Linux用のリポジトリがないので、rpmをダウンロードしてpgdg-redhat-all.repoを書き換える。 [ec2-user@postdb ~]$ wget https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm --2019-12-15 04:39:47-- https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm Resolving download.postgresql.org (download.postgresql.org)... 217.196.149.55, 72.32.157.246, 87.238.57.227, ... Connecting to download.postgresql.org (download.postgresql.org)|217.196.149.55|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 5932 (5.8K) [application/x-redhat-package-manager] Saving to: ‘pgdg-redhat-repo-latest.noarch.rpm’ 100%[==================================================================================================================================================>] 5,932 --.-K/s in 0s 2019-12-15 04:39:49 (189 MB/s) - ‘pgdg-redhat-repo-latest.noarch.rpm’ saved [5932/5932] [ec2-user@postdb ~]$ [ec2-user@postdb ~]$ sudo rpm -Uvh --nodeps pgdg-redhat-repo-latest.noarch.rpm warning: pgdg-redhat-repo-latest.noarch.rpm: Header V4 DSA/SHA1 Signature, key ID 442df0f8: NOKEY Preparing... ################################# [100%] Updating / installing... 1:pgdg-redhat-repo-42.0-5 ################################# [100%] [ec2-user@postdb ~]$ [ec2-user@postdb ~]$ sudo sed --in-place -e "s/\$releasever/7/g" /etc/yum.repos.d/pgdg-redhat-all.repo [ec2-user@postdb ~]$ [ec2-user@postdb ~]$ リポジトリ導入後のPostgreSQLパッケージの確認 [ec2-user@postdb ~]$ yum info postgresql10-server Loaded plugins: extras_suggestions, langpacks, priorities, update-motd amzn2-core | 2.4 kB 00:00:00 pgdg10 | 3.6 kB 00:00:00 pgdg11 | 3.6 kB 00:00:00 pgdg12 | 3.6 kB 00:00:00 pgdg94 | 3.6 kB 00:00:00 pgdg95 | 3.6 kB 00:00:00 pgdg96 | 3.6 kB 00:00:00 (1/12): pgdg12/x86_64/group_gz | 245 B 00:00:00 (2/12): pgdg11/x86_64/group_gz | 245 B 00:00:00 (3/12): pgdg10/x86_64/group_gz | 245 B 00:00:00 (4/12): pgdg94/x86_64/group_gz | 247 B 00:00:00 (5/12): pgdg95/x86_64/group_gz | 249 B 00:00:00 (6/12): pgdg12/x86_64/primary_db | 139 kB 00:00:00 (7/12): pgdg96/x86_64/group_gz | 249 B 00:00:00 (8/12): pgdg94/x86_64/primary_db | 389 kB 00:00:00 (9/12): pgdg96/x86_64/primary_db | 413 kB 00:00:00 (10/12): pgdg95/x86_64/primary_db | 401 kB 00:00:00 (11/12): pgdg10/x86_64/primary_db | 406 kB 00:00:02 (12/12): pgdg11/x86_64/primary_db | 362 kB 00:00:02 105 packages excluded due to repository priority protections Available Packages Name : postgresql10-server Arch : x86_64 Version : 10.11 Release : 2PGDG.rhel7 Size : 4.5 M Repo : pgdg10/x86_64 Summary : The programs needed to create and run a PostgreSQL server URL : https://www.postgresql.org/ License : PostgreSQL Description : PostgreSQL is an advanced Object-Relational database management system (DBMS). : The postgresql10-server package contains the programs needed to create : and run a PostgreSQL server, which will in turn allow you to create : and maintain PostgreSQL databases. [ec2-user@postdb ~]$ PostgreSQL11 と PostgreSQL12もインストール可能な状態。 [ec2-user@postdb ~]$ yum info postgresql11-server Loaded plugins: extras_suggestions, langpacks, priorities, update-motd 105 packages excluded due to repository priority protections Available Packages Name : postgresql11-server Arch : x86_64 Version : 11.6 Release : 2PGDG.rhel7 Size : 4.7 M Repo : pgdg11/x86_64 Summary : The programs needed to create and run a PostgreSQL server URL : https://www.postgresql.org/ License : PostgreSQL Description : PostgreSQL is an advanced Object-Relational database management system (DBMS). : The postgresql11-server package contains the programs needed to create : and run a PostgreSQL server, which will in turn allow you to create : and maintain PostgreSQL databases. [ec2-user@postdb ~]$ yum info postgresql12-server Loaded plugins: extras_suggestions, langpacks, priorities, update-motd 105 packages excluded due to repository priority protections Available Packages Name : postgresql12-server Arch : x86_64 Version : 12.1 Release : 2PGDG.rhel7 Size : 13 M Repo : pgdg12/x86_64 Summary : The programs needed to create and run a PostgreSQL server URL : https://www.postgresql.org/ License : PostgreSQL Description : PostgreSQL is an advanced Object-Relational database management system (DBMS). : The postgresql12-server package contains the programs needed to create : and run a PostgreSQL server, which will in turn allow you to create : and maintain PostgreSQL databases. [ec2-user@postdb ~]$ PostgreSQL10をインストールする。 [ec2-user@postdb ~]$ sudo yum -y install postgresql10-server Loaded plugins: extras_suggestions, langpacks, priorities, update-motd amzn2-core | 2.4 kB 00:00:00 pgdg10 | 3.6 kB 00:00:00 pgdg11 | 3.6 kB 00:00:00 pgdg12 | 3.6 kB 00:00:00 pgdg94 | 3.6 kB 00:00:00 pgdg95 | 3.6 kB 00:00:00 pgdg96 | 3.6 kB 00:00:00 (1/12): pgdg11/x86_64/group_gz | 245 B 00:00:01 (2/12): pgdg12/x86_64/group_gz | 245 B 00:00:01 (3/12): pgdg10/x86_64/group_gz | 245 B 00:00:01 (4/12): pgdg10/x86_64/primary_db | 406 kB 00:00:01 (5/12): pgdg11/x86_64/primary_db | 362 kB 00:00:01 (6/12): pgdg95/x86_64/group_gz | 249 B 00:00:00 (7/12): pgdg94/x86_64/group_gz | 247 B 00:00:00 (8/12): pgdg96/x86_64/group_gz | 249 B 00:00:00 (9/12): pgdg95/x86_64/primary_db | 401 kB 00:00:00 (10/12): pgdg12/x86_64/primary_db | 139 kB 00:00:01 (11/12): pgdg94/x86_64/primary_db | 389 kB 00:00:01 (12/12): pgdg96/x86_64/primary_db | 413 kB 00:00:01 105 packages excluded due to repository priority protections Resolving Dependencies --> Running transaction check ---> Package postgresql10-server.x86_64 0:10.11-2PGDG.rhel7 will be installed --> Processing Dependency: postgresql10-libs(x86-64) = 10.11-2PGDG.rhel7 for package: postgresql10-server-10.11-2PGDG.rhel7.x86_64 --> Processing Dependency: postgresql10(x86-64) = 10.11-2PGDG.rhel7 for package: postgresql10-server-10.11-2PGDG.rhel7.x86_64 --> Processing Dependency: libpq.so.5()(64bit) for package: postgresql10-server-10.11-2PGDG.rhel7.x86_64 --> Running transaction check ---> Package postgresql10.x86_64 0:10.11-2PGDG.rhel7 will be installed ---> Package postgresql10-libs.x86_64 0:10.11-2PGDG.rhel7 will be installed --> Finished Dependency Resolution Dependencies Resolved ================================================================================================================ Package Arch Version Repository Size ================================================================================================================ Installing: postgresql10-server x86_64 10.11-2PGDG.rhel7 pgdg10 4.5 M Installing for dependencies: postgresql10 x86_64 10.11-2PGDG.rhel7 pgdg10 1.6 M postgresql10-libs x86_64 10.11-2PGDG.rhel7 pgdg10 356 k Transaction Summary ================================================================================================================ Install 1 Package (+2 Dependent packages) Total download size: 6.5 M Installed size: 28 M Downloading packages: warning: /var/cache/yum/x86_64/2/pgdg10/packages/postgresql10-10.11-2PGDG.rhel7.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 442df0f8: NOKEY ] 979 kB/s | 960 kB 00:00:05 ETA Public key for postgresql10-10.11-2PGDG.rhel7.x86_64.rpm is not installed (1/3): postgresql10-10.11-2PGDG.rhel7.x86_64.rpm | 1.6 MB 00:00:01 (2/3): postgresql10-libs-10.11-2PGDG.rhel7.x86_64.rpm | 356 kB 00:00:02 (3/3): postgresql10-server-10.11-2PGDG.rhel7.x86_64.rpm | 4.5 MB 00:00:00 ----------------------------------------------------------- Total 2.7 MB/s | 6.5 MB 00:00:02 Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-PGDG Importing GPG key 0x442DF0F8: Userid : "PostgreSQL RPM Building Project <pgsqlrpms-hackers@pgfoundry.org>" Fingerprint: 68c9 e2b9 1a37 d136 fe74 d176 1f16 d2e1 442d f0f8 Package : pgdg-redhat-repo-42.0-5.noarch (installed) From : /etc/pki/rpm-gpg/RPM-GPG-KEY-PGDG Running transaction check Running transaction test Transaction test succeeded Running transaction ** Found 1 pre-existing rpmdb problem(s), 'yum check' output follows: pgdg-redhat-repo-42.0-5.noarch has missing requires of /etc/redhat-release Installing : postgresql10-libs-10.11-2PGDG.rhel7.x86_64 1/3 Installing : postgresql10-10.11-2PGDG.rhel7.x86_64 2/3 Installing : postgresql10-server-10.11-2PGDG.rhel7.x86_64 3/3 Verifying : postgresql10-libs-10.11-2PGDG.rhel7.x86_64 1/3 Verifying : postgresql10-server-10.11-2PGDG.rhel7.x86_64 2/3 Verifying : postgresql10-10.11-2PGDG.rhel7.x86_64 3/3 Installed: postgresql10-server.x86_64 0:10.11-2PGDG.rhel7 Dependency Installed: postgresql10.x86_64 0:10.11-2PGDG.rhel7 postgresql10-libs.x86_64 0:10.11-2PGDG.rhel7 Complete! [ec2-user@postdb ~]$ /usr/pgsql-10/bin/postgres --version postgres (PostgreSQL) 10.11 [ec2-user@postdb ~]$ OS側にpostgresユーザが作成される。 [ec2-user@postdb ~]$ cat /etc/passwd ~中略~ ec2-user:x:1000:1000:EC2 Default User:/home/ec2-user:/bin/bash postgres:x:26:26:PostgreSQL Server:/var/lib/pgsql:/bin/bash [ec2-user@postdb ~]$ postgresql10-contribとpostgresql10-develも合わせてインストールする。 [root@postdb ~]# yum install postgresql10-devel Loaded plugins: extras_suggestions, langpacks, priorities, update-motd 105 packages excluded due to repository priority protections Resolving Dependencies --> Running transaction check ---> Package postgresql10-devel.x86_64 0:10.11-2PGDG.rhel7 will be installed --> Processing Dependency: libicu-devel for package: postgresql10-devel-10.11-2PGDG.rhel7.x86_64 --> Running transaction check ---> Package libicu-devel.x86_64 0:50.1.2-17.amzn2 will be installed --> Finished Dependency Resolution Dependencies Resolved ============================================================================================ Package Arch Version Repository Size ============================================================================================ Installing: postgresql10-devel x86_64 10.11-2PGDG.rhel7 pgdg10 2.0 M Installing for dependencies: libicu-devel x86_64 50.1.2-17.amzn2 amzn2-core 702 k Transaction Summary ============================================================================================ Install 1 Package (+1 Dependent package) Total download size: 2.7 M Installed size: 13 M Is this ok [y/d/N]: n Exiting on user command Your transaction was saved, rerun it with: yum load-transaction /tmp/yum_save_tx.2019-12-28.11-00.54JiTC.yumtx [root@postdb ~]# [root@postdb ~]# yum install postgresql10-contrib Loaded plugins: extras_suggestions, langpacks, priorities, update-motd 105 packages excluded due to repository priority protections Resolving Dependencies --> Running transaction check ---> Package postgresql10-contrib.x86_64 0:10.11-2PGDG.rhel7 will be installed --> Processing Dependency: libxslt.so.1(LIBXML2_1.0.22)(64bit) for package: postgresql10-contrib-10.11-2PGDG.rhel7.x86_64 --> Processing Dependency: libxslt.so.1(LIBXML2_1.0.18)(64bit) for package: postgresql10-contrib-10.11-2PGDG.rhel7.x86_64 --> Processing Dependency: libxslt.so.1(LIBXML2_1.0.11)(64bit) for package: postgresql10-contrib-10.11-2PGDG.rhel7.x86_64 --> Processing Dependency: libxslt.so.1()(64bit) for package: postgresql10-contrib-10.11-2PGDG.rhel7.x86_64 --> Running transaction check ---> Package libxslt.x86_64 0:1.1.28-5.amzn2.0.2 will be installed --> Finished Dependency Resolution Dependencies Resolved ============================================================================================ Package Arch Version Repository Size ============================================================================================ Installing: postgresql10-contrib x86_64 10.11-2PGDG.rhel7 pgdg10 587 k Installing for dependencies: libxslt x86_64 1.1.28-5.amzn2.0.2 amzn2-core 243 k Transaction Summary ============================================================================================ Install 1 Package (+1 Dependent package) Total download size: 830 k Installed size: 2.5 M Is this ok [y/d/N]: y Downloading packages: (1/2): libxslt-1.1.28-5.amzn2.0.2.x86_64.rpm | 243 kB 00:00:00 (2/2): postgresql10-contrib-10.11-2PGDG.rhel7.x86_64.rpm | 587 kB 00:00:02 -------------------------------------------------------------------------------------------- Total 281 kB/s | 830 kB 00:00:02 Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : libxslt-1.1.28-5.amzn2.0.2.x86_64 1/2 Installing : postgresql10-contrib-10.11-2PGDG.rhel7.x86_64 2/2 Verifying : libxslt-1.1.28-5.amzn2.0.2.x86_64 1/2 Verifying : postgresql10-contrib-10.11-2PGDG.rhel7.x86_64 2/2 Installed: postgresql10-contrib.x86_64 0:10.11-2PGDG.rhel7 Dependency Installed: libxslt.x86_64 0:1.1.28-5.amzn2.0.2 Complete! [root@postdb ~]# DBの初期化を行う。rootで実施。 [root@postdb ~]# /usr/pgsql-10/bin/postgresql-10-setup initdb Initializing database ... OK 自動起動設定を行う [root@postdb ~]# systemctl enable postgresql-10 Created symlink from /etc/systemd/system/multi-user.target.wants/postgresql-10.service to /usr/lib/systemd/system/postgresql-10.service. PostgreSQLの起動、停止、再起動方法 sudo systemctl start postgresql-10.service sudo systemctl stop postgresql-10.service sudo systemctl restart postgresql-10.service [ec2-user@postdb pgsql-10]$ sudo systemctl start postgresql-10.service [ec2-user@postdb pgsql-10]$ echo $? 0 [ec2-user@postdb pgsql-10]$ ps -ef | grep postgres | grep -v grep postgres 4184 1 0 04:58 ? 00:00:00 /usr/pgsql-10/bin/postmaster -D /var/lib/pgsql/10/data/ postgres 4187 4184 0 04:58 ? 00:00:00 postgres: logger process postgres 4189 4184 0 04:58 ? 00:00:00 postgres: checkpointer process postgres 4190 4184 0 04:58 ? 00:00:00 postgres: writer process postgres 4191 4184 0 04:58 ? 00:00:00 postgres: wal writer process postgres 4192 4184 0 04:58 ? 00:00:00 postgres: autovacuum launcher process postgres 4193 4184 0 04:58 ? 00:00:00 postgres: stats collector process postgres 4194 4184 0 04:58 ? 00:00:00 postgres: bgworker: logical replication launcher [ec2-user@postdb pgsql-10]$ [ec2-user@postdb pgsql-10]$ [ec2-user@postdb pgsql-10]$ sudo systemctl stop postgresql-10.service [ec2-user@postdb pgsql-10]$ [ec2-user@postdb pgsql-10]$ [ec2-user@postdb pgsql-10]$ ps -ef | grep postgres | grep -v grep [ec2-user@postdb pgsql-10]$ [ec2-user@postdb pgsql-10]$ 接続してみる。 [ec2-user@postdb pgsql-10]$ su - postgres Password: Last login: Sun Dec 15 04:59:38 UTC 2019 on pts/1 -bash-4.2$ -bash-4.2$ psql --version psql (PostgreSQL) 10.11 -bash-4.2$ -bash-4.2$ -bash-4.2$ psql psql (10.11) Type "help" for help. postgres=# postgres=# select version(); version ---------------------------------------------------------------------------------------------------------- PostgreSQL 10.11 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39), 64-bit (1 row) --- ### PostgreSQLで論理レプリケーションするテーブルを追加 date: 2019-12-26 url: https://zatoima.github.io/postgresql-addtable-logical-replication.html tags: PostgreSQL はじめに CREATE PUBLICATIONする時に「FOR ALL TABLES」を付与するとそれ以降CREATE TABLEしたテーブルは自動的にレプリケーション対象になると思い込んでいた。初歩的なのかもしれないがこの動作を知らなかったのでメモ。 結論を書くと「FOR ALL TABLES」を付与している場合でも「ALTER SUBSCRIPTION xxxxxxx REFRESH PUBLICATION」コマンドが必要となる。 事前確認 Publisher側の設定確認。All tablesがTrueになっている。 repdb=> \dRp+ Publication alltables Owner | All tables | Inserts | Updates | Deletes ----------+------------+---------+---------+--------- postgres | t | t | t | t (1 row) Subscriber側の設定確認。logicalreplicationtestが既にレプリケーション対象となっている。 repdb=> SELECT repdb-> a3.subname, repdb-> a2.relname, repdb-> a1.srsubstate, repdb-> a1.srsublsn repdb-> FROM repdb-> pg_subscription_rel AS a1 repdb-> LEFT OUTER JOIN repdb-> pg_class AS a2 ON repdb-> a1.srrelid = a2.oid repdb-> LEFT OUTER JOIN repdb-> pg_stat_subscription AS a3 ON repdb-> a1.srsubid = a3.subid; subname | relname | srsubstate | srsublsn --------------------+------------------------+------------+----------- auroratopostgresql | logicalreplicationtest | r | 0/1220050 (1 row) テーブルを追加 Publisher側、Subscriber側でテーブルを作成する。 repdb=> CREATE TABLE addtable1 (a int PRIMARY KEY); CREATE TABLE 確認する。この時点でレプリケーション対象に追加されると思っていた。 repdb=> SELECT repdb-> a3.subname, repdb-> a2.relname, repdb-> a1.srsubstate, repdb-> a1.srsublsn repdb-> FROM repdb-> pg_subscription_rel AS a1 repdb-> LEFT OUTER JOIN repdb-> pg_class AS a2 ON repdb-> a1.srrelid = a2.oid repdb-> LEFT OUTER JOIN repdb-> pg_stat_subscription AS a3 ON repdb-> a1.srsubid = a3.subid; subname | relname | srsubstate | srsublsn --------------------+------------------------+------------+----------- auroratopostgresql | logicalreplicationtest | r | 0/1220050 (1 row) repdb=> ALTER SUBSCRIPTIONでREFRESHする。 repdb=> ALTER SUBSCRIPTION auroratopostgresql REFRESH PUBLICATION; ALTER SUBSCRIPTION ALTER SUBSCRIPTION https://www.postgresql.jp/document/10/html/sql-altersubscription.html REFRESH PUBLICATION 不足しているテーブル情報をパブリッシャーから取得します。 最後のREFRESH PUBLICATION、あるいはCREATE SUBSCRIPTIONの実行の後でサブスクライブ対象のパブリケーションに追加されたテーブルの複製が、これにより開始されます。 ここでようやくレプリケーション対象が増えた。 repdb=> SELECT repdb-> a3.subname, repdb-> a2.relname, repdb-> a1.srsubstate, repdb-> a1.srsublsn repdb-> FROM repdb-> pg_subscription_rel AS a1 repdb-> LEFT OUTER JOIN repdb-> pg_class AS a2 ON repdb-> a1.srrelid = a2.oid repdb-> LEFT OUTER JOIN repdb-> pg_stat_subscription AS a3 ON repdb-> a1.srsubid = a3.subid; subname | relname | srsubstate | srsublsn --------------------+------------------------+------------+----------- auroratopostgresql | logicalreplicationtest | r | 0/1220050 auroratopostgresql | addtable1 | r | 0/5030740 (2 rows) まとめ CREATE PUBLICATION側のマニュアルには"そのデータベース内の全テーブルについての変更を複製するもの"という記載があるのでこれからテーブル追加時に自動的にレプリケーションされるものと思い込んでいた。 https://www.postgresql.jp/document/10/html/sql-createpublication.html CREATE PUBLICATION FOR ALL TABLES そのパブリケーションでは、将来作成されるテーブルも含め、そのデータベース内の全テーブルについての変更を複製するものとして印をつけます。 レプリケーション対象のテーブルが増えたらALTER SUBSCRIPTION xxxxxxx REFRESH PUBLICATIONコマンドを実行しようという話。 --- ### Aurora(PostgreSQL)とRDS(PostgreSQL)の環境で論理レプリケーションする date: 2019-12-25 url: https://zatoima.github.io/aws-aurora-rds-postgresql-replication.html tags: AWS, Aurora, RDS, PostgreSQL はじめに PostgreSQL10から論理レプリケーションが使えるようになった。Auroraでもこの機能を使うことが出来るのでやってみる。基本的にここのドキュメントの通りやれば問題無し。 Aurora での PostgreSQL 論理レプリケーションの使用 - Amazon Aurora https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Replication.Logical.html 環境 Aurora PostgreSQL 10.7 と RDS PostgreSQL 10.7 間でレプリケーション環境を構築する マニュアル上の注意事項 rds.logical_replication パラメータを有効にすると、DB クラスターのパフォーマンスに影響します。 PostgreSQL データベースの論理レプリケーションを実行するために、AWS ユーザーアカウントは rds_superuser ロールを必要とします。 パブリッシャーの既存の Aurora PostgreSQL DB クラスターを使用するには、エンジンバージョンが 10.6 以降であることが必要です。 事前準備 rds.logical_replicationを「0」から「1」に設定する PostgreSQLからAurora側への通信をセキュリティグループで許可する 環境準備 レプリケーションを行うデータベースを作成 CREATE DATABASE repdb WITH OWNER postgres; レプリケーションを行うテーブルを用意する。PostgreSQL10時点の論理レプリケーションはDDLレプリケーションを行わないので、Publisher、及びSubscriber側で実施する必要がある。 \c repdb CREATE TABLE LogicalReplicationTest (a int PRIMARY KEY); Publisher側だけにデータを投入。 INSERT INTO LogicalReplicationTest VALUES (generate_series(1,10000)); Publisher側で"CREATE PUBLICATION"を実行。“FOR ALL TABLES"を指定してここではデータベース全体を行う方式を選択した。 https://www.postgresql.jp/document/10/html/sql-createpublication.html CREATE PUBLICATION FOR ALL TABLES そのパブリケーションでは、将来作成されるテーブルも含め、そのデータベース内の全テーブルについての変更を複製するものとして印をつけます。 #repdbに接続 \c repdb CREATE PUBLICATION alltables FOR ALL TABLES; Subscriber側で"CREATE SUBSCRIPTION"を実行。 #repdbに接続 \c repdb CREATE SUBSCRIPTION auroratopostgresql CONNECTION 'host=aurorapostgresqlv1.cluster-xxxxxxxxx.ap-northeast-1.rds.amazonaws.com port=5432 dbname=repdb user=postgres password=postgres' PUBLICATION alltables; ログを確認すると、レプリケーションが始まっていることが確認できる。(初期同期の模様。) 2019-12-14 09:25:49 UTC::@:[16112]:LOG: logical replication table synchronization worker for subscription "auroratopostgresql", table "logicalreplicationtest" has started 2019-12-14 09:25:49 UTC::@:[16112]:LOG: logical replication table synchronization worker for subscription "auroratopostgresql", table "logicalreplicationtest" has finished pg_subscription_relを確認することでどのテーブルが論理レプリケーション対象となっているか確認可能。 SELECT * FROM pg_subscription_rel; repdb=> SELECT * FROM pg_subscription_rel; srsubid | srrelid | srsubstate | srsublsn ---------+---------+------------+---------- 16425 | 16417 | d | (1 row) repdb=> select relname from pg_class where oid=16417; relname ------------------------ logicalreplicationtest (1 row) repdb=> レプリケーション設定はpg_replication_slotsビューから確認可能。 repdb=> select * from pg_replication_slots; -[ RECORD 1 ]-------+------------------- slot_name | auroratopostgresql plugin | pgoutput slot_type | logical datoid | 24590 database | repdb temporary | f active | t active_pid | 19407 xmin | catalog_xmin | 23236 restart_lsn | 0/4F8C710 confirmed_flush_lsn | 0/4F8CAE8 Publisher側のpg_publicationからは作成した定義情報が確認できる。データベース内のすべてのテーブルをレプリケーション対象としたので「puballtables」が「True」になっている。 repdb=> select * from pg_publication; -[ RECORD 1 ]+---------- pubname | alltables pubowner | 16393 puballtables | t pubinsert | t pubupdate | t pubdelete | t --- ### PostgreSQL論理レプリケーションの遅延監視 date: 2019-12-22 url: https://zatoima.github.io/postgresql-logical-replication-monitoring.html tags: AWS, Aurora, RDS, PostgreSQL はじめに 論理レプリケーションを行う時の遅延監視について整理してみる。環境はAWSのAurora、及びRDSのPostgreSQL互換を使用。バージョンは10.7。 WALの読み込み位置の確認 repdb=> select pg_current_wal_lsn(); -[ RECORD 1 ]------+---------- pg_current_wal_lsn | 0/4F94888 レプリケーション遅延の確認 Publisher側でpg_stat_replicationビューを確認して確認が可能。 \x select * from pg_stat_replication; repdb=> select * from pg_stat_replication; -[ RECORD 1 ]----+------------------------------ pid | 19407 usesysid | 16393 usename | postgres application_name | auroratopostgresql client_addr | xxx.xxx.xxx.xx client_hostname | client_port | 46478 backend_start | 2019-12-14 09:24:19.187306+00 backend_xmin | state | streaming sent_lsn | 0/4F67640 write_lsn | 0/4F67640 flush_lsn | 0/4F67640 replay_lsn | 0/4F67640 write_lag | 00:00:01.582706 flush_lag | 00:00:01.985095 replay_lag | 00:00:01.582706 sync_priority | 0 sync_state | async repdb=> WALログの位置が重要。sent_lsn、write_lsn、flush_lsn、replay_lsn等から位置が特定できる。 列 型 説明 sent_lsn pg_lsn この接続で送信された最後の先行書き込みログの位置です。 write_lsn pg_lsn このスタンバイサーバによってディスクに書き出された最後の先行書き込みログ位置です。 flush_lsn pg_lsn このスタンバイサーバによってディスクに吐き出された最後の先行書き込みログ位置です。 replay_lsn pg_lsn このスタンバイサーバ上のデータベースに再生された最後の先行書き込みログ位置です。 28.2. 統計情報コレクタ https://www.postgresql.jp/document/10/html/monitoring-stats.html#PG-STAT-REPLICATION-VIEW sent_lsn、write_lsn、flush_lsn、replay_lsnは下記のような関係性だと予想。(要検証)ここのlsnの位置を使うことで、Publisher側の問題なのか、ネットワークの問題なのか、Subscriberの適用の問題なのかがわかる。 また、stateからもWAL Senderの状態がわかる。 WAL送信サーバの現在の状態です。 取り得る値は以下の通りです。 startup: このWAL送信サーバは起動するところです。 catchup: このWAL送信サーバが接続しているスタンバイはプライマリに追いつこうとしています。 streaming: このWAL送信サーバは、接続先のスタンバイサーバがプライマリに追いついた後、変更をストリーミングしています。 backup: このWAL送信サーバはバックアップを送信しています。 stopping: このWAL送信サーバは停止するところです。 とは言え、遅延確認という観点だとpg_stat_replicationの更新頻度が 『write or flush lsnの位置が変更があったとき』、もしくは 『“wal_receiver_status_interval"で指定された秒数』となるため、後述の方法を使って判断した方が良いと考える。wal_receiver_status_intervalはデフォルト10秒のため、WALの適用が終わっているにも関わらず、更新されないという自体が起きうる。wal_receiver_status_intervalの10秒が経過後、pg_stat_replicationを確認したタイミングでようやくわかる。wal_receiver_status_intervalを調整した環境や常にレプリケーションが走っている状況の場合は有用のはず。 PostgreSQLのLSNは16進数となるので一見したところ位置の比較が不明な場合があるので、その場合は「pg_wal_lsn_diff」関数を使う。出力される情報はバイトであることに注意。 https://www.postgresql.jp/document/10/html/functions-admin.html pg_wal_lsn_diffは、2つの先行書き込みログの位置の差分をバイト数で算出します。 この関数はpg_stat_replicationや表 9.79に示される関数と併用することで、レプリケーションの遅延の確認に使用できます。 SELECT pg_wal_lsn_diff(sent_lsn,write_lsn) write_diff, pg_wal_lsn_diff(sent_lsn,flush_lsn) flush_diff, pg_wal_lsn_diff(sent_lsn,replay_lsn) replay_diff FROM pg_stat_replication; 1.) 差分がある場合: repdb=> select pg_wal_lsn_diff(sent_lsn,write_lsn) write_diff, pg_wal_lsn_diff(sent_lsn, flush_lsn) flush_diff, pg_wal_lsn_diff(sent_lsn,replay_lsn) replay_diff from pg_stat_replication; -[ RECORD 1 ]--------- write_diff | 26749408 flush_diff | 26749408 replay_diff | 26749408 2.) 差分がない場合: repdb=> select pg_wal_lsn_diff(sent_lsn,write_lsn) write_diff, pg_wal_lsn_diff(sent_lsn, flush_lsn) flush_diff, pg_wal_lsn_diff(sent_lsn,replay_lsn) replay_diff from pg_stat_replication; -[ RECORD 1 ]-- write_diff | 0 flush_diff | 0 replay_diff | 0 Subscriber側で確認する方法としては下記がある。時間がわかるので直感的にわかりやすい。 repdb=> select * from pg_stat_subscription; -[ RECORD 1 ]---------+------------------------------ subid | 16425 subname | auroratopostgresql pid | 15008 relid | received_lsn | 0/4F87048 last_msg_send_time | 2019-12-14 09:40:29.125815+00 last_msg_receipt_time | 2019-12-14 09:40:29.135405+00 latest_end_lsn | 0/4F87048 latest_end_time | 2019-12-14 09:40:29.125815+00 --- ### RDS(PostgreSQL)の論理レプリケーションの競合エラーを解消する date: 2019-12-13 url: https://zatoima.github.io/aws-rds-repllication-error-conflict.html tags: AWS, RDS, PostgreSQL 競合を発生させる #subscribe側のテーブルに事前にINSERTする insert into LogicalReplicationTest values (1); #publisher側のテーブルにINSERTして伝搬させる insert into LogicalReplicationTest values (1); エラー確認 2019-11-30 15:13:26 UTC::@:[29680]:ERROR: duplicate key value violates unique constraint "logicalreplicationtest_pkey" 2019-11-30 15:13:26 UTC::@:[29680]:DETAIL: Key (a)=(1) already exists. 2019-11-30 15:13:26 UTC::@:[12125]:LOG: worker process: logical replication worker for subscription 110499 (PID 29680) exited with exit code 1 この時の方針としては大きく2つある。 競合が発生した原因を取り除く 上記の場合は、publisher側のテーブルに既にデータが入っていることが原因なので、publisher側をメンテナンスする。 publisher側のLSNの適用位置を変更する 今回は上記の「2.publisher側のLSNの適用位置を変更する」をやってみる。あるべき姿は「1.競合が発生した原因を取り除く」 現時点のLSNの位置を確認 select * from pg_show_replication_origin_status(); rdb=> select * from pg_show_replication_origin_status(); local_id | external_id | remote_lsn | local_lsn ----------+-------------+------------+------------ 1 | pg_110499 | 0/306DC150 | B/E103DA48 (1 row) Publisher側のWALのLSNの位置を確認 SELECT pg_current_wal_lsn(); rdb=> SELECT pg_current_wal_lsn(); pg_current_wal_lsn -------------------- 0/306E3BF8 (1 row) Subscribe側のLSNの位置を変更 SELECT pg_replication_origin_advance('pg_110499', '0/306E3BF8'); rdb=> select * from pg_show_replication_origin_status(); local_id | external_id | remote_lsn | local_lsn ----------+-------------+------------+----------- 1 | pg_43450 | 0/3006B190 | 0/0 (1 row) 読み取り位置が変更されることにより、競合が発生しなくなる。 --- ### いまいちどOracle Databaseのデータ移行方法について考えてみる date: 2019-12-11 url: https://zatoima.github.io/oracle-jpoug-migration-database.html tags: Oracle, Migration この記事は JPOUG Advent Calendar 2019 11日目の記事です!10日目は Naotaka Shinogi さんの データベースをNutanixの上で動かすことを考える でした。Nutanix Eraに興味を惹かれてNutanix社にカジュアル面談に行ったことを思い出しました。 1.移行について Oracle to Oracleのアップグレード、クラウド化プロジェクトを想定します。システム移行と聞くとそのプロジェクトに関係していなくてもドキドキしますが、特にデータベースのアップグレードイベントは一際注目度が高くなると思います。一大イベントです。データベースに格納されているデータは業務の根幹ですし、データベースに問題があるとシステム全体に影響があるので重要度が上がるのだと思っています。如何に「リスクを少なく」、「短時間」で「何事もなく」行えるかがDBAの腕の見せどころだと思います。ユーザ影響やその他の影響度の大小はもちろんあると思いますが、データベースのアップグレード時に数日単位で止められる方が難しいのではないかと思います。可能であればゼロダウンタイム、止めても数時間、1日という要件が多いように感じます。移行後も新旧並行稼動して新システム側の更新を旧システム側に反映…という要件も。AWSのRDSを始めとしたクラウドサービスやOSSのPostgreSQLやMySQLがある中でOracle Databaseを使い続けるという選択をする場合なので、利用者の多い重要なシステムであるということは違わないと思います。 Data Pump(昔からのシステムからの移行であればimp/exp)を使うデータ移行の方法が従来からよく使われていたと思います。一番最初に関わったプロジェクトがそうでした。このプロジェクトでは移行時間を多く確保していました。データ移行後に本当にデータの整合性が確保されているか件数確認や実際のデータを確認したり。システム基盤更改だけではなく業務要件対応も一緒に実施していたので、移行ツールの開発などが大変でした。データベース移行は「simple is best」をやはり心掛けるべきだな、と感じました。と言っても現行データベースの分析を行っていくと、他システムと連携をdblinkを使っており、移行の順番を考えないといけない。筐体に乗っているシステムごとに移行しないといけない、等のデータベース単体では収まらない事情が多く発生してくると思います。 前置きが長くなりましたが、移行時のダウンタイムを減らす、移行の確実性を高めるためといった目的のためににどのような手段が取られるかと言うと差分同期を行う移行デザインパターンが一番頭に浮かびます。例えば次のようなケースです。 移行日の数週間前 :一定の断面を確保し、移行先へデータを持っていく 移行日の数週間前~移行日当日まで:差分同期を逐次実施 当日 :差分同期の追いつきを確認後、切替を行う このユースケースの最たる例がOracle GoldenGate、AWS Database Migration Serviceあたりが有名な差分同期の製品やサービスではないかと思います。当日のリスクを移行日以前に持ってくるケースです。 2.Oracle Databaseのデータ移行手段 ご存知の通り、Oracle Databaseは多くのデータの移行手段を用意しています。 export/import(※旧バージョンからの移行のみ) Data Pump トランスポータブル表領域 クロスプラットフォーム・トランスポータブル表領域 増分バックアップを利用したトランスポータブル表領域 増分クロスプラットフォーム・トランスポータブル表領域 フル・トランスポータブルexport/import Oracle GoldenGate バックアップからの複製 Data Guard スタンバイからのプライマリ昇格 Oracle Zero Downtime Migration(※Oracle Cloud上への移行に限る) 参考: Oracle Databaseのアップグレード・移行ベストプラクティスのご紹介 https://www.oracle.com/technetwork/jp/content/upgrade-patch-seminar-2654134-ja.pdf 今回は、この中から「増分トランスポータブル表領域」と「Oracle Zero Downtime Migration」について書いてみます。選定理由としては「増分バックアップを利用したトランスポータブル表領域」はダウンタイムを極力減らすことが出来るソリューションにも関わらずあまり使われていないと思ったのと、Web上にあまり「やってみた」系記事がなかったことから選びました。「Oracle Zero Downtime Migration」は最近リリースされたOracle Cloudへデータを移行するための方法ですが、「Zero Downtime」のアーキテクチャが気になったため選びました。「Oracle Zero Downtime Migration」も実機で試してみたのですが、途中でエラーになってハマってしまった時間が足りなかったので机上で調査した内容をまとめてみます。 3.増分バックアップを利用したトランスポータブル表領域 増分バックアップを利用したトランスポータブル表領域のメリットや有効性については、JPOUG Advent Calendar 2016 の コーソル 渡部さんの記事にも記載されています。合わせてご参照ください。 RMANの差分増分バックアップ機能とフル・トランスポータブル・エクスポート/インポート機能を活用してダウンタイムを極力短くしたデータベース移行方法の図を書いてみた (コーソル DatabaseエンジニアのBlog) [http : //cosol.jp/techdb/2016/12/illustrate-full-transportable-export-import-with-rman-incremental-backup.html](http : //cosol.jp/techdb/2016/12/illustrate-full-transportable-export-import-with-rman-incremental-backup.html) ちなみに、MOSにはCross Platform Transportable Tablespace with Incremental Backupを主題に置いた下記のhow to のナレッジがありますが、私が確認する限りマニュアルには手順は用意されていないと思っています。 V4 Reduce Transportable Tablespace Downtime using Cross Platform Incremental Backup (ドキュメントID 2471245.1) また、2471245.1 のドキュメントですが、Perlスクリプトを使ってデータ移行を行うため、内部的にどのような処理やコマンドが使われるのかがわかりません。なので、手動で増分バックアップを利用したトランスポータブル表領域を実施してみます。Doc 2471245.1 を参考にしているのでおそらく合っていると思いますが、実際にこの手法を使って移行する場合は上記ドキュメントのPerlスクリプトを使って移行した方が良いと思います。色々と多機能です。SCNの管理も自動で行ってくれます。 増分バックアップを利用したトランスポータブル表領域の手順の流れ 1.準備フェーズ(ソースデータはオンラインのまま) ​ ー 表領域のフルバックアップ(Level0) ​ ー バックアップセットをターゲットDB側に転送する 2.フルバックアップ(Level0)のリストア ​ ー ソースDBで取得したバックアップセットをターゲットDBにロールフォワードする 3.ソースシステムで増分バックアップを取得してターゲットシステムに適用 ​ ー 増分バックアップセットをターゲットDB側に転送する。移行先のデータファイルに適用 4.メタデータの取得、移行 ​ ー 移行元データベースをREAD ONLYに変更してロールフォワードフェーズを最後に行う ​ ー Data Pumpを使用して、表領域内のオブジェクトのメタデータを移行先データベースにインポート ​ ー 移行先データベースの表領域をREAD WRITEに変更 イメージ図 移行日より前に特定時点のフルバックアップとフルバック以降に発生した差分データを事前に移行することによってダウンタイムが縮小化できます。 実行環境 移行元:12.1.0.2 移行先:19.3 手順 1.ブロック・チェンジ・トラッキングの有効化 今回は増分バックアップを使用するのでブロック・チェンジ・トラッキング・ファイル(変更追跡ファイル)を有効化します。これによりバックアップ取得を高速化出来ます。増分バックアップの際には、このファイルを元にデータ変更が行われたブロックだけをダイレクトに読み込むことが出来るため、バックアップ所要時間を短縮できます。 ALTER DATABASE ENABLE BLOCK CHANGE TRACKING; 2.level0のバックアップの取得 ソース側のSCNを確認する。 SQL> select current_scn from v$database; CURRENT_SCN ----------- 3450645 level 0 のバックアップを取得します。今回はTTSという表領域を移行対象とします。[必要に応じてトランスポートする表領域セットが自己完結型であることを確認](https : //docs.oracle.com/cd/E57425_01/121/ARPLS/d_tts.htm)する必要があります。 rman target / backup for transport allow inconsistent incremental level 0 format '/home/oracle/rman/tts_level0.bkp' tablespace tts; backupが開始されました(開始時間 : 19-12-11) チャネルORA_DISK_1の使用 チャネルORA_DISK_1 : 増分レベル0のデータファイル・バックアップ・セットを開始しています チャネルORA_DISK_1 : バックアップ・セットにデータファイルを指定しています 入力データファイル・ファイル番号=00014 名前=/u01/app/oracle/oradata/DB121S/datafile/o1_mf_tts_gystzx22_.dbf チャネルORA_DISK_1 : ピース1(19-12-11)を起動します チャネルORA_DISK_1 : ピース1(19-12-11)が完了しました ピース・ハンドル=/home/oracle/rman/tts_level0.bkp タグ=TAG20191211T135511 コメント=NONE チャネルORA_DISK_1 : バックアップ・セットが完了しました。経過時間 : 00 : 00 : 01 backupが完了しました(完了時間 : 19-12-11) 3.ターゲット側でLevel0のバックアップからリストアする ターゲット側でrestoreする restore all foreign datafiles to new from backupset '/home/oracle/rman/tts_level0.bkp'; [oracle@dbsrvec2 ~]$ rman target / Recovery Manager : Release 19.0.0.0.0 - Production on 水 12月 11 13 : 46 : 43 2019 Version 19.3.0.0.0 Copyright (c) 1982, 2019, Oracle and/or its affiliates. All rights reserved. ターゲット・データベース : DB19C (DBID=2154771102)に接続されました RMAN> restore all foreign datafiles to new from backupset '/home/oracle/rman/tts_level0.bkp'; restoreを19-12-11で開始しています チャネルORA_DISK_1の使用 チャネルORA_DISK_1 : データファイル・バックアップ・セットのリストアを開始しています チャネルORA_DISK_1 : バックアップ・セットからリストアするデータファイルを指定しています チャネルORA_DISK_1 : バックアップ・ピースのすべての外部ファイルをリストアしています チャネルORA_DISK_1 : バックアップ・ピース/home/oracle/rman/tts_level0.bkpから読取り中です チャネルORA_DISK_1 : 外部ファイル14を/u01/app/oracle/oradata/DB19C/datafile/o1_mf_tts_gz1xbopy_.dbfにリストアしています チャネルORA_DISK_1 : 外部ピース・ハンドル/home/oracle/rman/tts_level0.bkp チャネルORA_DISK_1 : バックアップ・ピース1がリストアされました チャネルORA_DISK_1 : リストアが完了しました。経過時間 : 00 : 00 : 02 restoreを19-12-11で終了しました DB_CREATE_FILE_DESTが設定されていないとエラーになります。「RMAN-05088 : DB_CREATE_FILE_DESTが設定されていません」 ALTER SYSTEM SET DB_CREATE_FILE_DEST = '/u01/app/oracle/oradata/db19c' SCOPE = both; 4.増分バックアップの取得 再度ソース側のSCNを確認する。 SQL> select current_scn from v$database; CURRENT_SCN ----------- 3450702 次はlevel 1 の増分バックアップを取得します。ここで指定するSCNは一番最初に取得したSCNを指定します。 backup for transport allow inconsistent incremental from scn 3450645 format '/home/oracle/rman/tts_level1.bkp' tablespace tts; RMAN> backup for transport allow inconsistent incremental from scn 3450645 format '/home/oracle/rman/tts_level1.bkp' tablespace tts; backupが開始されました(開始時間 : 19-12-11) チャネルORA_DISK_1の使用 チャネルORA_DISK_1 : フル・データファイル・バックアップ・セットを開始しています チャネルORA_DISK_1 : バックアップ・セットにデータファイルを指定しています 入力データファイル・ファイル番号=00014 名前=/u01/app/oracle/oradata/DB121S/datafile/o1_mf_tts_gystzx22_.dbf チャネルORA_DISK_1 : ピース1(19-12-11)を起動します チャネルORA_DISK_1 : ピース1(19-12-11)が完了しました ピース・ハンドル=/home/oracle/rman/tts_level1.bkp タグ=TAG20191211T135615 コメント=NONE チャネルORA_DISK_1 : バックアップ・セットが完了しました。経過時間 : 00 : 00 : 01 backupが完了しました(完了時間 : 19-12-11) ちなみに移行元側で更新がない場合はエラー(skip)になります。 RMAN-06755 : 警告 : データファイル14 : 増分起動SCNが新しすぎます。かわりにチェックポイントSCN 3304366を使用しています チャネルORA_DISK_1 : フル・データファイル・バックアップ・セットを開始しています チャネルORA_DISK_1 : バックアップ・セットにデータファイルを指定しています 入力データファイル・ファイル番号=00014 名前=/u01/app/oracle/oradata/DB121S/datafile/o1_mf_tts_gystzx22_.dbf データファイル00014は、変更がないためスキップします チャネルORA_DISK_1 : 全ファイルがスキップされたため、バックアップは取り消されました backupが完了しました(完了時間 : 19-12-11) 5.増分バックアップの適用 増分バックアップをデータファイルに適用します。ここで指定するデータファイルは上記のrestoreコマンドを実行した時に出力されるデータファイルです。 recover foreign datafilecopy '/u01/app/oracle/oradata/DB19C/datafile/o1_mf_tts_gz1xbopy_.dbf' from backupset '/home/oracle/rman/tts_level1.bkp'; RMAN> recover foreign datafilecopy '/u01/app/oracle/oradata/DB19C/datafile/o1_mf_tts_gz1xbopy_.dbf' from backupset '/home/oracle/rman/tts_level1.bkp'; restoreを19-12-11で開始しています チャネルORA_DISK_1の使用 チャネルORA_DISK_1 : データファイル・バックアップ・セットのリストアを開始しています チャネルORA_DISK_1 : バックアップ・セットからリストアするデータファイルを指定しています チャネルORA_DISK_1 : 外部ファイル/u01/app/oracle/oradata/DB19C/datafile/o1_mf_tts_gz1xbopy_.dbfをリストアしています チャネルORA_DISK_1 : バックアップ・ピース/home/oracle/rman/tts_level1.bkpから読取り中です チャネルORA_DISK_1 : 外部ピース・ハンドル/home/oracle/rman/tts_level1.bkp チャネルORA_DISK_1 : バックアップ・ピース1がリストアされました チャネルORA_DISK_1 : リストアが完了しました。経過時間 : 00 : 00 : 01 restoreを19-12-11で終了しました 移行日が来るまで任意のタイミングで"増分バックアップを作成"と"増分バックアップの適用"フェーズを繰り返します。 6.最終分の増分バックアップの適用、及びメタデータの取得 移行日当日の作業となります。このタイミングから移行元データベースはダウンタイムが発生します。移行対象のTTSを読み取り専用にします。 alter tablespace tts read only; 表領域が現在読み取り専用になっている最後の増分バックアップを作成する。データファイルを移行先データベースでトランスポータブルするためにメタデータを取得します。 backup for transport incremental from scn 3450702 format '/home/oracle/rman/tts_last.bkp' tablespace tts DATAPUMP FORMAT '/home/oracle/rman/dp_tts_ts.dmp'; RMAN> backup for transport incremental from scn 3450702 format '/home/oracle/rman/tts_last.bkp' tablespace tts DATAPUMP FORMAT '/home/oracle/rman/dp_tts_ts.dmp'; backupが開始されました(開始時間 : 19-12-11) チャネルORA_DISK_1の使用 指定された表領域でTRANSPORT_SET_CHECKを実行しています TRANSPORT_SET_CHECKは正常に終了しました 指定された表領域のメタデータをエクスポートしています... EXPDP> "SYS"."TRANSPORT_EXP_DB121S_bCex"を起動しています : EXPDP> オブジェクト型TRANSPORTABLE_EXPORT/PLUGTS_BLKの処理中です EXPDP> オブジェクト型TRANSPORTABLE_EXPORT/TABLEの処理中です EXPDP> オブジェクト型TRANSPORTABLE_EXPORT/CONSTRAINT/CONSTRAINTの処理中です EXPDP> オブジェクト型TRANSPORTABLE_EXPORT/INDEX_STATISTICSの処理中です EXPDP> オブジェクト型TRANSPORTABLE_EXPORT/TABLE_STATISTICSの処理中です EXPDP> オブジェクト型TRANSPORTABLE_EXPORT/STATISTICS/MARKERの処理中です EXPDP> オブジェクト型TRANSPORTABLE_EXPORT/POST_INSTANCE/PLUGTS_BLKの処理中です EXPDP> マスター表"SYS"."TRANSPORT_EXP_DB121S_bCex"は正常にロード/アンロードされました EXPDP> ****************************************************************************** EXPDP> SYS.TRANSPORT_EXP_DB121S_bCexに設定されたダンプ・ファイルは次のとおりです : EXPDP> /u01/app/oracle/product/12.1.0.2/dbhome_1/dbs/backup_tts_DB121S_17308.dmp EXPDP> ****************************************************************************** EXPDP> トランスポータブル表領域TTSにはデータファイルが必要です : EXPDP> /u01/app/oracle/oradata/DB121S/datafile/o1_mf_tts_gystzx22_.dbf EXPDP> ジョブ"SYS"."TRANSPORT_EXP_DB121S_bCex"が水 12月 11 14 : 02 : 24 2019 elapsed 0 00 : 00 : 47で正常に完了しました エクスポートが完了しました チャネルORA_DISK_1 : フル・データファイル・バックアップ・セットを開始しています チャネルORA_DISK_1 : バックアップ・セットにデータファイルを指定しています 入力データファイル・ファイル番号=00014 名前=/u01/app/oracle/oradata/DB121S/datafile/o1_mf_tts_gystzx22_.dbf チャネルORA_DISK_1 : ピース1(19-12-11)を起動します チャネルORA_DISK_1 : ピース1(19-12-11)が完了しました ピース・ハンドル=/home/oracle/rman/tts_last.bkp タグ=TAG20191211T140131 コメント=NONE チャネルORA_DISK_1 : バックアップ・セットが完了しました。経過時間 : 00 : 00 : 01 チャネルORA_DISK_1 : フル・データファイル・バックアップ・セットを開始しています 入力データ・ポンプ・ダンプ・ファイル=/u01/app/oracle/product/12.1.0.2/dbhome_1/dbs/backup_tts_DB121S_17308.dmp チャネルORA_DISK_1 : ピース1(19-12-11)を起動します チャネルORA_DISK_1 : ピース1(19-12-11)が完了しました ピース・ハンドル=/home/oracle/rman/dp_tts_ts.dmp タグ=TAG20191211T140131 コメント=NONE チャネルORA_DISK_1 : バックアップ・セットが完了しました。経過時間 : 00 : 00 : 01 backupが完了しました(完了時間 : 19-12-11) データファイルに最後の適用を行います。 recover foreign datafilecopy '/u01/app/oracle/oradata/DB19C/datafile/o1_mf_tts_gz1xbopy_.dbf' from backupset '/home/oracle/rman/tts_last.bkp'; RMAN> recover foreign datafilecopy '/u01/app/oracle/oradata/DB19C/datafile/o1_mf_tts_gz1xbopy_.dbf' from backupset '/home/oracle/rman/tts_last.bkp'; restoreを19-12-11で開始しています チャネルORA_DISK_1の使用 チャネルORA_DISK_1 : データファイル・バックアップ・セットのリストアを開始しています チャネルORA_DISK_1 : バックアップ・セットからリストアするデータファイルを指定しています チャネルORA_DISK_1 : 外部ファイル/u01/app/oracle/oradata/DB19C/datafile/o1_mf_tts_gz1xbopy_.dbfをリストアしています チャネルORA_DISK_1 : バックアップ・ピース/home/oracle/rman/tts_last.bkpから読取り中です チャネルORA_DISK_1 : 外部ピース・ハンドル/home/oracle/rman/tts_last.bkp チャネルORA_DISK_1 : バックアップ・ピース1がリストアされました チャネルORA_DISK_1 : リストアが完了しました。経過時間 : 00 : 00 : 01 restoreを19-12-11で終了しました 最終的なバックアップセットからメタデータエクスポートダンプを取得する。 restore dump file datapump destination '/u01/app/oracle/admin/db19c/dpdump' from backupset '/home/oracle/rman/dp_tts_ts.dmp'; RMAN> restore dump file datapump destination '/u01/app/oracle/admin/db19c/dpdump' from backupset '/home/oracle/rman/dp_tts_ts.dmp'; restoreを19-12-11で開始しています チャネルORA_DISK_1の使用 チャネルORA_DISK_1 : データファイル・バックアップ・セットのリストアを開始しています チャネルORA_DISK_1 : バックアップ・セットからリストアするデータファイルを指定しています チャネルORA_DISK_1 : データ・ポンプ・ダンプ・ファイルを/u01/app/oracle/admin/db19c/dpdump/backup_tts_DB19C_54885.dmpにリストアしています チャネルORA_DISK_1 : バックアップ・ピース/home/oracle/rman/dp_tts_ts.dmpから読取り中です チャネルORA_DISK_1 : 外部ピース・ハンドル/home/oracle/rman/dp_tts_ts.dmp チャネルORA_DISK_1 : バックアップ・ピース1がリストアされました チャネルORA_DISK_1 : リストアが完了しました。経過時間 : 00 : 00 : 02 restoreを19-12-11で終了しました 7.トランスポータブル実行! このメタデータを移行先にインポートすることによって、これまでせっせとrecover(適用)してきたデータファイルを移行先でようやく使えるようになります。 impdp system/oracle directory=data_pump_dir dumpfile=backup_tts_DB19C_54885.dmp logfile=backup_tts_DB19C_54885.log transport_datafiles='/u01/app/oracle/oradata/DB19C/datafile/o1_mf_tts_gz1xbopy_.dbf'; [oracle@dbsrvec2 ~]$ impdp system/oracle directory=data_pump_dir dumpfile=backup_tts_DB19C_54885.dmp logfile=backup_tts_DB19C_54885.log transport_datafiles='/u01/app/oracle/oradata/DB19C/datafile/o1_mf_tts_gz1xbopy_.dbf'; Import : Release 19.0.0.0.0 - Production on 水 12月 11 14 : 07 : 18 2019 Version 19.3.0.0.0 Copyright (c) 1982, 2019, Oracle and/or its affiliates. All rights reserved. 接続先 : Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production マスター表"SYSTEM"."SYS_IMPORT_TRANSPORTABLE_01"は正常にロード/アンロードされました "SYSTEM"."SYS_IMPORT_TRANSPORTABLE_01"を起動しています : system/******** directory=data_pump_dir dumpfile=backup_tts_DB19C_54885.dmp logfile=backup_tts_DB19C_54885.log transport_datafiles=/u01/app/oracle/oradata/DB19C/datafile/o1_mf_tts_gz1xbopy_.dbf オブジェクト型TRANSPORTABLE_EXPORT/PLUGTS_BLKの処理中です ORA-39123 : データ・ポンプ・トランスポータブル表領域ジョブが異常終了しました。 ORA-29342 : ユーザーTTSはデータベースに存在しません。 ジョブ"SYSTEM"."SYS_IMPORT_TRANSPORTABLE_01"は致命的なエラーのため水 12月 11 14 : 07 : 22 2019 elapsed 0 00 : 00 : 02で停止しました ユーザを作成します。この時点でTTS表領域は存在しないため、デフォルト表領域は指定しません。 SQL> create user tts identified by "oracle"; ユーザーが作成されました。 SQL> grant dba to tts; 権限付与が成功しました。 ワンモアチャレンジ。 [oracle@dbsrvec2 ~]$ impdp system/oracle directory=data_pump_dir dumpfile=backup_tts_DB19C_54885.dmp logfile=backup_tts_DB19C_54885.log transport_datafiles='/u01/app/oracle/oradata/DB19C/datafile/o1_mf_tts_gz1xbopy_.dbf'; Import : Release 19.0.0.0.0 - Production on 水 12月 11 14 : 08 : 56 2019 Version 19.3.0.0.0 Copyright (c) 1982, 2019, Oracle and/or its affiliates. All rights reserved. 接続先 : Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production マスター表"SYSTEM"."SYS_IMPORT_TRANSPORTABLE_01"は正常にロード/アンロードされました "SYSTEM"."SYS_IMPORT_TRANSPORTABLE_01"を起動しています : system/******** directory=data_pump_dir dumpfile=backup_tts_DB19C_54885.dmp logfile=backup_tts_DB19C_54885.log transport_datafiles=/u01/app/oracle/oradata/DB19C/datafile/o1_mf_tts_gz1xbopy_.dbf オブジェクト型TRANSPORTABLE_EXPORT/PLUGTS_BLKの処理中です オブジェクト型TRANSPORTABLE_EXPORT/TABLEの処理中です オブジェクト型TRANSPORTABLE_EXPORT/CONSTRAINT/CONSTRAINTの処理中です オブジェクト型TRANSPORTABLE_EXPORT/INDEX_STATISTICSの処理中です オブジェクト型TRANSPORTABLE_EXPORT/TABLE_STATISTICSの処理中です オブジェクト型TRANSPORTABLE_EXPORT/STATISTICS/MARKERの処理中です オブジェクト型TRANSPORTABLE_EXPORT/POST_INSTANCE/PLUGTS_BLKの処理中です ジョブ"SYSTEM"."SYS_IMPORT_TRANSPORTABLE_01"が水 12月 11 14 : 09 : 09 2019 elapsed 0 00 : 00 : 13で正常に完了しました TTS表領域が作成されています。ttsユーザのデフォルト表領域も変更しておきます。 SQL> select TABLESPACE_NAME from dba_tablespaces; TABLESPACE_NAME -------------------------------------------------------------------------------- SYSTEM SYSAUX UNDOTBS1 TEMP USERS TTS 6行が選択されました。 SQL> alter user tts DEFAULT TABLESPACE tts; ユーザーが変更されました。 移行先で表領域を書き込み可能に変更して終わりです。 alter tablespace tts read write; 所感 上記の通り、他移行方法と比べて大きな特徴があります。GoldenGateの代わりになるとは言い切れませんが、+αのコストを掛けずに移行したい、ダウンタイムを減らしたい、バージョンアップをしたい、という場合にはこの方法も使えるのではないでしょうか。 4.Oracle Zero Downtime Migrationについて はじめに Oracleが提供するZero Downtime Migrationツールのアーキテクチャ、中身、コンセプトを知りたくて資料を眺めていました。始めは実際にやってみて使用感の確認や本当に使えるか試してAdavanced Calendarのネタにしたかったのですがエラーにハマり諦めました。概要レベルだけまとめてみます。インプット情報は全て下記のマニュアルとホワイトペーパーです。 https://www.oracle.com/database/technologies/rac/zdm.html https://docs.oracle.com/en/database/oracle/zero-downtime-migration/ https://www.oracle.com/technetwork/database/options/clustering/learnmore/oracle-zdm-wp-5869851.pdf Oracle Zero Downtime Migrationの概要 大きく分けて2つの機能があるようです。 Data Guardを使用したZero Downtime Migration オフライン(バックアップと復元)移行 「Data Guardを使用したZero Downtime Migration」の大まかなstepは 公式ページ の 8 Simple Automated Steps を見ればわかります。 ZDM/Agentのインストール&セットアップ(※別途100GB以上のストレージを持ったOracle Linux7以上の環境が必要です) ZDMの起動 移行元のデータベースとObject Storageを接続 Object StorageにRMANを使用してバックアップを取得 Data Guardスタンバイを作成(4.のバックアップを使用) Data Guardで同期 スイッチオーバー 移行元と移行先のコネクションの終了、ソースとターゲット環境のクリーンアップ 一方、「オフライン(バックアップと復元)移行」はData Guardを使用できないStandard Edtition用に用意された機能です。とは言え、「オフライン(バックアップと復元)」移行の方の詳細はマニュアルやホワイトペーパーからはあまり確認できませんでした。オフラインの場合は特にソースデータベースとターゲットデータベース側でネットワーク接続は不要です。なお、“zdm_template_zdmsdb.rsp"ファイルがあるのでそこでData Guardを使用したMigrationをするのかオフライン(object storage経由)の移行をするのかを選択します。 次にホワイトペーパーを眺めてみます。ベースとして使用されている機能はData Guardと明確に述べています。 ZDM automates the entire process of migration, reducing the chance of human errors. ZDM leverages Oracle Database-integrated high availability (HA) technologies such as Oracle Data Guard and follows all MAA best practices that ensures zero to no downtime of production environments サポートしているバージョンは11.2.0.4 ~ 19cが対象です。 Oracle ZDM supports the following Oracle Database versions : • 11.2.0.4 • 12.1.0.2 • 12.2.0.1 • 18c • 19c Data Guardをベースとしたソリューションのために、Oracle Zero Downtime Migrationでは同じバージョンのデータベースのみMigrationが可能です。 The source and target databases should be in the same database version. Oracle ZDM supports Oracle Databases hosted on Linux operating systems. The source database can be a single instance database migrating to a single instance or a RAC database, or it can also be a RAC One Node / RAC database, migrating to a RAC database. Standard Edition がData Guardを使用できないと同様にZero Downtime MigrationでもData Guardではない他の手段を使ってMigrationする必要があります。 Oracle ZDM supports Enterprise & Standard Edition Oracle Databases as source databases. Enterprise Edition Databases are migrated leveraging Oracle Data Guard; Standard Edition Databases are migrated in an offline manner using a backup and restore methodology. 詳細ステップはこちら。ZDMCLI コマンドを使用することで自動実行が出来ます。 フェーズ名 説明 ZDM_GET_SRC_INFO ソースデータベースに関する情報を取得する ZDM_GET_TGT_INFO ターゲットデータベースに関する情報を取得する ZDM_SETUP_SRC 移行元サーバーでゼロダウンタイム移行ヘルパーモジュールをセットアップする ZDM_SETUP_TGT ターゲットサーバーでゼロダウンタイム移行ヘルパーモジュールをセットアップする ZDM_PREUSERACTIONS 移行前のユーザーアクションがあれば、ソースで実行する ZDM_PREUSERACTIONS_TGT ターゲットで移行の事前ユーザーアクション(存在する場合)を実行する ZDM_OBC_INST_SRC ソースにOracle Database Cloud Backup Moduleをインストールします ZDM_OBC_INST_TGT ターゲットにOracle Database Cloud Backup Moduleをインストールします ZDM_GEN_RMAN_PASSWD RMANバックアップを暗号化するためのランダムパスワードを生成する ZDM_BACKUP_FULL_SRC ソースデータベースの完全バックアップを実行する ZDM_BACKUP_INCREMENTAL_SRC ソースデータベースの増分バックアップを実行する ZDM_VALIDATE_SRC ソースで検証を実行する ZDM_VALIDATE_TGT ターゲットで検証を実行します ZDM_DISCOVER_SRC Data Guardを設定するためにソースでデータベース検出を実行します ZDM_COPYFILES OracleパスワードファイルとTDEウォレットをソースからターゲットにコピーします ZDM_OSS_STANDBY_SETUP_TDE_TGT TDEウォレットファイルをソースからターゲットキーストアの場所にコピーします ZDM_PREPARE_TGT Data Guardスタンバイ作成のターゲットを準備する ZDM_CLONE_TGT クラウドバックアップからData Guardスタンバイを作成する ZDM_FINALIZE_TGT ターゲットのData Guardスタンバイ準備を完了します ZDM_CONFIGURE_DG_SRC クラウドスタンバイをソースに登録する ZDM_SWITCHOVER_SRC ソースでスイッチオーバーアクションを開始する ZDM_SWITCHOVER_TGT ターゲットでスイッチオーバーアクションを完了する ZDM_POSTUSERACTIONS ソースで移行後のユーザーアクションを実行する ZDM_POSTUSERACTIONS_TGT ターゲットで移行後のユーザーアクションを実行する ZDM_CLEANUP_SRC ソースでクリーンアップを実行します ZDM_CLEANUP_TGT ターゲットでクリーンアップを実行します 所感 当初、Zero Downtime Migrationという言葉からはOracle GoldenGateが思い浮かびましたが、実際にはData Guardの機能で行うようです。同じバージョンでしか使えないので"バージョンアップを伴う"Cloud移行には使えないのがネックかと思いました。単純にクラウド移行を行うためだけのツールという理解に至りました。Data Guardのモード(同期/非同期)や非同期の場合、適用ラグがあった場合の動作が気になります。また、マニュアルを見る限り移行元データベース側の事前準備としてData Guardの設定変更に関する記載が無かったように思いました。DGはForce Logging必須ではなかった?実際に最後まで動かせていないので詳細までは記載出来なかったのが心残りです。 最後に よりよい移行方法を使って楽をしましょう! 数ヶ月前からPelicanというフレームワークを使いGithub Pages上にホストしているのですが、使い勝手が悪すぎるので早速ブログ移行したいです。 --- ### RDS(PostgreSQL)でpg_replication_origin_statusにアクセス出来ない(permission denied) date: 2019-12-10 url: https://zatoima.github.io/aws-rds-pg-replication-origin-status-error.html tags: AWS, RDS, PostgreSQL バージョン rdbtest=> select version(); version --------------------------------------------------------------------------------------- PostgreSQL 10.7 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5 -11), 64-bit 事象 pg_replication_origin_statusの情報をselectしようとするとpermission deniedでエラーが発生する。rds_superuserロールだとしても同様。この情報はsubscriber に反映されている変更のトランザクションログの位置(LSN)の位置とpublisher側のLSNの対応関係が記載されているので、この情報が見れないと論理レプリケーション時の運用時に困る。 rdbtest=> SELECT * FROM pg_replication_origin_status; ERROR: permission denied for relation pg_replication_origin_status 対応策 pg_show_replication_origin_status()にアクセスしてLSNを取得する。 rdbtest=> select * from pg_show_replication_origin_status(); local_id | external_id | remote_lsn | local_lsn ----------+-------------+------------+----------- 1 | pg_43450 | 0/28D70910 | 0/0 (1 row) 参考 AWS Developer Forums: RDS Postgres Logical replication access … https://forums.aws.amazon.com/thread.jspa?threadID=301094 --- ### Pelicanのメリット、デメリット date: 2019-12-09 url: https://zatoima.github.io/pelican-pros-and-cons.html tags: Pelican, Blog メリット 読み込み速度が高速 Pythonベース Github Pagesにホストするのでコストが掛からない。 Git関連の知識が(多少)付く 構築やカスタマイズがめんどくさいので自分のブログ感が出る Github上で自動的にバージョン管理 記事の編集はMarkdownだけで完結する(はてなは最終的には ブログサイト 側を更新する必要があった) デメリット 記事作成毎にHTML生成が必要 管理画面無い(CUIベースで出来るというメリットも。) 記事のカテゴリーを一つしか選べない ネット上にあまり日本語情報がないので英語マニュアルを読む必要がある(公式ドキュメントは充実している) PelicanのThemesやコミュニティが下火気味? 記事生成処理はPelicanをインストールした環境で行う必要がある URLの自動リンクがされない(テーマによる?既存のプラグインは確認できない) その他 独自ドメインは設定可能 Google Analyticsも設定可能 SEOは現在のところ不明 動的ページを生成できない。問い合わせフォームとかは設置できない。(Google Adsenceを行う場合はアウトかも) おまけ WebPageTestでPerformanceを確認してみた WebPageTest - Website Performance and Optimization Test https://www.webpagetest.org/ 結論 静的サイト、めちゃ早い 当サイト(https://zatoima.github.io/) 阿部寛のホームページ http://abehiroshi.la.coocan.jp/ --- ### PostgreSQLのpg_dump、pg_restoreについてまとめる date: 2019-12-03 url: https://zatoima.github.io/postgresql-about-pg_dump-pg_restore.html tags: PostgreSQL, pg_dump, pg_restore はじめに これから何度も調べることになりそうなので、PostgreSQLのpg_dump、pg_restoreについてまとめておく。 スクリプトファイル形式とアーカイブファイル形式でバックアップが可能。それぞれでリストア方式が異なる。 スクリプトファイル形式の論理バックアップ : psqlでリストア アーカイブファイル形式の論理バックアップ : pg_restoreでリストア 基本コマンド 1.スクリプトファイル形式の論理バックアップ データベース単位のバックアップ ​ mydbという名前のデータベースをSQLスクリプトファイルにダンプ pg_dump mydb > db.sql テーブル単位のバックアップ mytabという名前の単一のテーブルをダンプ pg_dump -t mytab mydb > db.sql リストア newdbというデータベースにdb.sqlの内容をリストア psql -d newdb -f db.sql 2.アーカイブファイル形式の論理バックアップ この場合、圧縮されるため、データやデータ型にも依存するが一定のデータが減る。 データベース単位のバックアップ ​ mydbという名前のデータベースをアーカイブファイル形式にダンプ。 pg_dump -Fc mydb > db.dump テーブル単位のバックアップ mytabという名前の単一のテーブルをアーカイブファイル形式にダンプ pg_dump -t mytab -Fc mydb > db.dump リストア newdbというデータベースにdb.dumpの内容をリストア pg_restore -d newdb db.dump 3.コマンドのオプション pg_dump 引数(省略系) 引数 説明 -a –data-only データのみをダンプし、スキーマ(データ定義)はダンプしない -b –blobs ラージオブジェクトをダンプに含める。 –schema、–table、–schema-onlyが指定された場合を除き、これがデフォルトの動作 -c –clean データベースオブジェクトを作成するコマンドの前に、データベースオブジェクトを整理(削除)するコマンドを書き出す。スクリプト形式の場合にのみ有効。 -C –create 初めにデータベース自体を作成するコマンドを出力し、その後、作成したデータベースに接続するコマンドを出力する。スクリプト形式の場合にのみ有効。 -f file –file=file 出力を指定のファイルに書き出す -F format –format=format p/plain 平文のSQLスクリプトファイルを出力 c/custom pg_restoreへの入力に適したカスタム形式アーカイブを出力 -s –schema-only データ定義(スキーマ)のみをダンプし、データはダンプしない -j njobs –jobs=njobs njobs個のテーブルを同時にダンプすることによって、並行してダンプを実行 -d dbname –dbname=dbname 接続するデータベースの名前を指定 -h host –host=host サーバが稼働しているマシンのホスト名を指定 -p port –port=port サーバが接続を監視するTCPポート -U username –username=username 接続ユーザ名を指定 pg_restore 引数(省略系) 引数 説明 -a –data-only データのみをダンプし、スキーマ(データ定義)はダンプしない -c –clean 再作成前にデータベースオブジェクトを整理(削除) -C –create リストア前にデータベースを作成 -d dbname –dbname=dbname dbnameデータベースに接続し、このデータベースに直接リストア -e –exit-on-error データベースにSQLコマンドを送信中にエラーが発生した場合、処理を終了 -F format –format=format pg_restoreは形式を自動認識するので、このオプションは必須ではない p/plain 平文のSQLスクリプトファイルを出力 c/custom pg_restoreへの入力に適したカスタム形式アーカイブを出力 -j njobs –jobs=njobs データのロード、インデックスの作成、制約の作成部分を複数の同時実行ジョブを使用して実行 -s –schema-only アーカイブ内にあるスキーマ項目の範囲でスキーマ(データ定義)のみをリストアし、データ(テーブルの内容)をリストアしない -h host –host=host サーバが稼働しているマシンのホスト名を指定 -p port –port=port サーバが接続を監視するTCPポート -U username –username=username 接続ユーザ名を指定 -v –verbose 冗長モードを指定 4.個人的によく使うコマンド例 AWSのRDS等で使う場合はリモートホストに対して実行することになるので、-hオプションが必要。 テーブルのデータのみ pg_dump でexport(カスタムモード) pg_dump -h aurorapostgresdb.xxxxxxx.ap-northeast-1.rds.amazonaws.com -U <ユーザ名> -a -t <Table名> -Fc <DB名> > rds01.custom rds01に接続してインポート前にオブジェクトを削除してインポートする pg_restore -v -h aurorapostgresdb.xxxxxxx.ap-northeast-1.rds.amazonaws.com -U <ユーザ名> -c -C -d <DB名> /home/ec2-user/rds01_dump_2.custom スキーマ定義のみインポートする pg_restore -v -h rdspostgresql1.xxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -U <ユーザ名> -s -d <DB名> /home/ec2-user/rds01_dump_2.custom データのみインポートする pg_restore -v -h aurorapostgresdb.xxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -U <ユーザ名> -a -d <DB名> /home/ec2-user/rds01_dump_2.custom リストア時にパラレルで実行する(8並列で実行) pg_restore -h aurorapgsqlv1.cluster-xxxxxx.ap-northeast-1.rds.amazonaws.com -U postgres -j 8 -d tpcc tpcc.dump 参考 pg_dump https://www.postgresql.jp/document/10/html/app-pgdump.html pg_restore https://www.postgresql.jp/document/10/html/app-pgrestore.html --- ### AWS Transfer for SFTPを使ってS3にアップロード date: 2019-11-29 url: https://zatoima.github.io/aws-sftp-for-s3.html tags: AWS, SFTP awscliではなくsftpコマンドでS3にアップロードしたい!そういうときのマネージドサービス。 SFTPサーバの起動/作成 サービス一覧からAWS Transfer fot SFTPを選択して"Creaete Server"をクリック Endpoint configurationでEndpoint typeを選択する。ここではPublicを選択。Logging RoleやTagは必要に応じて。 ユーザの作成 ロールを指定するがこの時S3のアクセス権が必要。 AssumeRole が必要だったはず。 SFTP のための IAM ポリシーおよびロールの作成 - AWS Transfer for SFTP https://docs.aws.amazon.com/ja_jp/transfer/latest/userguide/requirements-roles.html ユーザを作成する時に必要な登録用の鍵を作る 登録した公開鍵をユーザ作成画面で登録する [ec2-user@walt-dev-ec2 ~]$ ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/ec2-user/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/ec2-user/.ssh/id_rsa. Your public key has been saved in /home/ec2-user/.ssh/id_rsa.pub. The key fingerprint is: SHA256:FGSySPzbCkxTDDiX/NYhnKP2ko/CTIrR2r/lZef83k4 ec2-user@walt-dev-ec2 接続 作成した鍵を使ってsftpを実行。接続できた。 [ec2-user@walt-dev-ec2 ~]$ sftp -i .ssh/id_rsa sftp-user@s-9ec720a3add94f11a.server.transfer.ap-northeast-1.amazonaws.com Connected to s-9ec720a3add94f11a.server.transfer.ap-northeast-1.amazonaws.com. sftp> sftp> ls -l drwxr--r-- 1 - - 0 Jan 1 1970 pluto-dev-s3-test drwxr--r-- 1 - - 0 Jan 1 1970 z3-cloudtrail-s3-test --- ### Pelican on Github Pages構築後のカスタマイズについて date: 2019-11-25 url: https://zatoima.github.io/pelican-customize-setting.html tags: Blog, Pelican はじめに Pelican導入後にこの5つをやったので備忘のためにも整理する pelican-bootstrap3の設定 Google Analyticsの導入 サイトのfaviconを設定 pelicanconf.pyのカスタマイズ 検索エンジン対策 1. pelican-bootstrap3を設定する pelican-bootstrap3はこういうデザインのテーマ。 pelicanのオフィシャルのthemesを全てcloneする git clone --recursive https://github.com/getpelican/pelican-themes ~/pelican-themes pelicanconf.pyのTHEME変数を修正する。 THEME = 'pelican-themes\\pelican-bootstrap3' pelican-bootstrap3の場合は下記設定も必須。他のthemeの場合は不要だった。 JINJA_ENVIRONMENT = { 'extensions': ['jinja2.ext.i18n'], } 2.Google Analyticsの導入 Goole Analytics側の設定方法自体はググればたくさんあると思うので割愛。 PelicanのGoole Analyticsの導入は非常に簡単。公開用の設定ファイルであるpublishconf.pyにGoogle Analytics用の変数があるためにそこに「UA-XXXXXX」を設定すれば完了。 GOOGLE_ANALYTICS = "UA-********-*" GOOGLE_ANALYTICS_SITEID = "auto" 3.faviconの設定 pelican-bootstrap3を使っている場合は、事前にfaviconとするicoファイルを配置した上で設定ファイル(pelicanconf.py)に下記のように設定するだけで良い。 # for favicon setting FAVICON = 'images/favicon.ico' themeに依存していることが多いと思うので、上記以外の場合はこの辺の記事が参考になると思われる。 Tips n Tricks · getpelican/pelican Wiki https://github.com/getpelican/pelican/wiki/Tips-n-Tricks [Python]Pelicanで作ったサイトにfaviconを設定する - dackdive’s blog https://dackdive.hateblo.jp/entry/2016/01/12/101200 4.pelicanconf.pyのカスタマイズ pelican-bootstrap3向けのカスタマイズ pelican-bootstrap3のthemesに依存するのでこのテーマ以外は動作しないはず。 参考URL→ https://github.com/getpelican/pelican-themes/tree/master/pelican-bootstrap3 # customize for pelican-bootstrap3 2019.11.17 # 記事にカテゴリを追加するか SHOW_ARTICLE_CATEGORY=True # breadcrumbs パンくずリストを表示するかどうか DISPLAY_BREADCRUMBS=True DISPLAY_CATEGORY_IN_BREADCRUMBS=True # 記事一覧に Date や Category、 Tagsを表示させるかどうか DISPLAY_ARTICLE_INFO_ON_INDEX=True # バナー画像に関するカスタマイズ #BANNER = 'images/banner.jpg' #BANNER_ALL_PAGES = True # カテゴリ DISPLAY_CATEGORIES_ON_SIDEBAR=True # タグ DISPLAY_TAGS_ON_SIDEBAR=True # 最近の投稿の表示(デフォルト5つの記事を表示) DISPLAY_RECENT_POSTS_ON_SIDEBAR=True その他全体の設定変更 #cjk_spacing:Markdown ドキュメント中の中国語/日本語/韓国語と英単語との間にスペースを挿入 #markdown_cjk_spacing/README-ja.md at master · EloiseSeverin/markdown_cjk_spacing https://github.com/EloiseSeverin/markdown_cjk_spacing/blob/master/README-ja.md MARKDOWN = { 'extension_configs': { 'markdown.extensions.codehilite': {'css_class': 'highlight'}, 'markdown.extensions.extra': {}, 'markdown.extensions.meta': {}, 'markdown.extensions.nl2br': {}, 'markdown_cjk_spacing.cjk_spacing': {}, }, 'output_format': 'html5', } # add for date format 2019.11.17 DATE_FORMATS = { 'en': '%a, %d %b %Y', 'ja': '%Y-%m-%d(%a)', } DEFAULT_LANG = 'Ja' # Feed generation is usually not desired when developing FEED_ALL_ATOM = None CATEGORY_FEED_ATOM = None TRANSLATION_FEED_ATOM = None AUTHOR_FEED_ATOM = None AUTHOR_FEED_RSS = None DEFAULT_PAGINATION = 5 # Uncomment following line if you want document-relative URLs when developing #RELATIVE_URLS = True 5.検索エンジン対策 はてなブログと違ってGithub PagesはCEOは期待できないので 自分の公開したいURLないしはドメインをエンジン側に申請する。GoogleとBingに今回作ったURLを登録する。こちらのURLから出来る。 Google Search Console Bing Webマスターツール --- ### Pelican on Github Pagesで静的サイトを構築する date: 2019-11-23 url: https://zatoima.github.io/pelican-blog-implement.html tags: Blog, Pelican 静的サイトとは? Github PagesやS3上で静的ファイルを置いて外部に公開できる仕組み。静的サイトを構築するジェネレーターはたくさんあるが、今回はPelicanで作っている。理由はPythonで作られているフレームワークという点でPelicanを選択してみた。構築自体も簡単だった。(基本的にCUIや設定ファイルを書き換えることで変更を行うので慣れるまで多少時間が掛かる気がする) 日本語サイトでネットでよく見る静的サイトジェネレーターは、Hugo、Hexoあたりかな、と。色々な種類あるのでこのリンクも見てどうぞ。 StaticGen | Top Open Source Static Site Generators 前提事項 gitインストール済 Pythonインストール済 Windows10 Pelicanインストール 環境を汚さないようにvirtualenvでpythonの仮想環境を作る cd C:\ virtualenv pelican cd pelican Scripts\activate pelican、markdownをpipでインストール pip install pelican pip install Markdown Pelican4.2がインストールされる (pelican) C:\pelican>pelican --version 4.2.0 ブログの雛形を作成** pelican-quickstartコマンドを実行すると対話形式で色々聞かれる。 pelican-quickstart > Where do you want to create your new web site? [.] > What will be the title of this web site? zatolog > Who will be the author of this web site? zato > What will be the default language of this web site? [en] ja > Do you want to specify a URL prefix? e.g., http://example.com (Y/n) Y > What is your URL prefix? (see above example; no trailing slash) http://zatoima.github.io > Do you want to enable article pagination? (Y/n) Y > How many articles per page do you want? [10] 5 > What is your time zone? [Europe/Paris] Asia/Tokyo > Do you want to generate a Fabfile/Makefile to automate generation and publishing? (Y/n) Y > Do you want an auto-reload & simpleHTTP script to assist with theme and site development? (Y/n) Y > Do you want to upload your website using FTP? (y/N) N > Do you want to upload your website using SSH? (y/N) N > Do you want to upload your website using Dropbox? (y/N) N > Do you want to upload your website using S3? (y/N) N > Do you want to upload your website using Rackspace Cloud Files? (y/N) N > Do you want to upload your website using GitHub Pages? (y/N) y > Is this your personal page (username.github.io)? (y/N) y Done. markdown形式で記事を作る 適当にファイルを作成してcontentフォルダ配下に保存する Title: My First Review Date: 2010-12-03 10:20 Category: Review Slug: pelican-my-first-review Following is a review of my favorite mechanical keyboard. 「Title」、「Date」、「Category」、「Slug」が記事のメタデータとなる。SlugはページのURL名(HTML名)となる。 Windowsの追加手順 本来ならmakeコマンドで簡単に静的ページを生成できるが、Windowsでは出来ないのでバッチファイルを使う。下記からダウンロードしたbatファイルをPelicanをインストールしたフォルダ直下に配置。(C:\pelican) https://gist.github.com/traeblain/4252511 一部修正する必要あり。 修正前 set _PELICAN=$pelican set _PELICANOPTS=$pelicanopts . . cd %_OUTPUTDIR% && python -m SimpleHTTPServer 修正後 set _PELICAN=pelican set _PELICANOPTS= . . cd %_OUTPUTDIR% && python -m http.server ※デフォルトでは"http.server"は8000ポートを使う。もし他サービス8000ポート使っていればエラーになるため、必要に応じて他のポートを使うように書き換える cd %_OUTPUTDIR% && python -m http.server 8080 htmlファイルの作成 pmake htmlコマンドでmarkdownからhtmlファイルを作成し、pmake serveコマンドでlocalhostにサーバが起動されローカルで作成記事の確認が出来る。 pmake html pmake serve アクセス先 http://localhost:8000 Githubに公開する手順 Pelicanフォルダ配下の全てのファイルをGithub Pagesにアップロードしても良いが、不要なファイルが多く存在する。ghp-importを使うことで 指定したディレクトリをgh-pagesブランチにしてくれる。 下記では「output」フォルダがgh-pagesブランチになって、「output」フォルダの中のみがpushされる。 cd C:\pelican Scripts\Activate pip install ghp-import pmake html pmake publish ghp-import output git commit -m "Update Post" git push https://github.com/zatoima/zatoima.github.io.git gh-pages:master git push後に数分待って自分のgithub pagesにアクセスする。※下記ページは既にtheme変更後のページ。 Pelican themeの変更方法 themeの変更はすごく簡単。ただ、themeによって設定できる項目が違っているのでカスタマイズを進めると他のthemeには変えづらくなる。(どこのブログサービスも同じか) pelicanのオフィシャルのthemesを全てcloneする git clone --recursive https://github.com/getpelican/pelican-themes ~/pelican-themes pelicanconf.pyのTHEME変数を修正する。 THEME = 'pelican-themes\\pelican-bootstrap3' Pluginの導入方法 pelicanのオフィシャルのpluginを全てcloneする git clone --recursive https://github.com/getpelican/pelican-plugins.git pelican-plugins pelicanconf.pyのPLUGIN_PATHS変数、PLUGINS変数を修正する。PLUGIN_PATHSには上記でcloneしたディレクトリを指定 PLUGIN_PATHS = ['pelican-plugins'] PLUGINS = ['i18n_subsites','tag_cloud','sitemap','series'] Appendix WebPageTestでWebページ表示までのパフォーマンスを確認してみた。阿部寛のサイトにも勝てそう。 WebPageTest - Website Performance and Optimization Test https://www.webpagetest.org/ --- ### トランザクション分離レベル(ISOLATION LEVEL)と各DBエンジンについて date: 2019-11-17 url: https://zatoima.github.io/oracle-mysql-postgresql-isolation-level.html tags: Oracle, MySQL, PostgreSQL RDBMS製品のACID特性のI(Isolation)に関わるメモ トランザクション分離レベルとは? まずはトランザクション分離レベルの基本的な考え方について整理。 SERIALIZABLE ( 直列化可能 ) 複数の並行に動作するトランザクションそれぞれの結果が、いかなる場合でも、それらのトランザクションを時間的重なりなく逐次実行した場合と同じ結果となる。このような性質を直列化可能性(Serializability)と呼ぶ。SERIALIZABLEは最も強い分離レベルであり、最も安全にデータを操作できるが、相対的に性能は低い。ただし同じ結果とされる逐次実行の順はトランザクション処理のレベルでは保証されない。 REPEATABLE READ ( 読み取り対象のデータを常に読み取る ) ひとつのトランザクションが実行中の間、読み取り対象のデータが途中で他のトランザクションによって変更される心配はない。同じトランザクション中では同じデータは何度読み取りしても毎回同じ値を読むことができる。 ただし ファントム・リード(Phantom Read) と呼ばれる現象が発生する可能性がある。ファントム・リードでは、並行して動作する他のトランザクションが追加したり削除したデータが途中で見えてしまうため、処理の結果が変わってしまう。 READ COMMITTED ( 確定した最新データを常に読み取る ) 他のトランザクションによる更新については、常にコミット済みのデータのみを読み取る。 MVCC はREAD COMMITTEDを実現する実装の一つである。 ファントム・リード に加え、非再現リード(Non-Repeatable Read)と呼ばれる、同じトランザクション中でも同じデータを読み込むたびに値が変わってしまう現象が発生する可能性がある。 READ UNCOMMITTED ( 確定していないデータまで読み取る) 他の処理によって行われている、書きかけのデータまで読み取る。 PHANTOM 、 NON-REPEATABLE READ 、さらに ダーティ・リード(Dirty Read) と呼ばれる現象(不完全なデータや、計算途中のデータを読み取ってしまう動作)が発生する。トランザクションの並行動作によってデータを破壊する可能性は高いが、その分性能は高い。 トランザクション分離レベル - Wikipedia https://ja.wikipedia.org/wiki/トランザクション分離レベル 上記のトランザクション分離レベルによって起こりうる Transaction Annomaly が異なる。 Dirty Read トランザクションT1がデータを変更し、COMMITかROLLBACKをする前に、トランザクションT2がそのデータを読む。その後T1がROLLBACKした場合、T2はCOMMITされていない=実在しないデータを読んだことになる。 Fuzzy Read(Non-Repeatable Read) トランザクションT1がデータを読んだ後、トランザクションT2がそのデータを変更もしくは削除してCOMMITする。その後T1がデータを再度読もうとすると、データが変更されている、もしくは削除されていることが検知される。 Phantom Read トランザクションT1が、ある検索条件に基づいてデータ集合を読む。その後、トランザクションT2がその検索条件を満たすデータを作成しCOMMITする。T1が再度同じ検索条件で読み取りを行うと、最初に得られたデータ集合と異なるデータ集合が得られる。 Lost Update トランザクションT1はデータ項目を読み取り、T2はデータ項目を以前の読み取り値に基づいて更新し、T1はデータ項目を更新して以前の読み取り値に基づいてコミットする。トランザクションT2の更新がトランザクションT1に上書きされてしまうのでT2のUpdateがLostするということでLost Updateと言う。 更新したはずのデータが失われてしまう現象のことで、後勝ち処理とも言うと聞いたことがある。なので、他のAnnomaly と比べて異常という感じはしない。しっかりトランザクション管理しましょうね、という話だと思っている。 具体例を記載しておく。本の在庫管理のトランザクションを想定。 ①現在、在庫が90冊あるとして、100冊を下回った場合、不足分を補充するように追加注文する処理があったとする。 ②【Tx2】Tx2で現在の90冊を取得した。 ③【Tx1】次にTx1で同じく現在90冊ということを取得。 ④【Tx1】10冊を購入処理して、在庫が100冊と更新する。 Write Skew T1がxとyを読み取り、次にT2がxとyを読み取りxを書き込みコミットする。 次にT1はyを書き込む。 xとyの間に制約がある場合、違反となる。 つまり、2つの並行トランザクションがそれぞれ、他方が書き込んでいるものと重複するデータセットの読み取りに基づいて書き込み内容が決まる場合(y=x+1とか)、一方が他方より先に実行された場合には発生し得ない状態を取得できる 具体的なケースはこちら「Black and White」や「Intersecting Data」あたりのケースを見てトランザクションの動きを見るべき。 ssi - postgresql wiki https://wiki.postgresql.org/wiki/SSI 分離レベルと起こりうるTransaction Annomaly ISOの定義上のトランザクション分離レベルで上記のこの3つのTransaction Annomalyの発生有無は下記の通りである。しかし、DBエンジンの実装上、READ COMMITTEDだが、Fuzzy Readは発生しないとかなっているケースがあるので注意が必要。 A Critique of ANSI SQL Isolation Levels https://arxiv.org/ftp/cs/papers/0701/0701157.pdf 各DBエンジンとトランザクション分離レベルの対応表 DBエンジンで選択可能な分離レベルが異なります。DBエンジンを変更する場合はトランザクション分離レベルの理解が必要です。トランザクションで発行するSQLのタイミングによって取得されるデータが異なってきます。 isolation level Oracle PostgreSQL MySQL SERIALIZABLE ○ ○ ○ REPEATABLE READ × ○ ○(※デフォルト) READ COMMITTED ○(※デフォルト) ○(※デフォルト) ○ READ UNCOMMITTED × ○ ○ MySQL :: MySQL 5.6 リファレンスマニュアル :: 13.3.6 SET TRANSACTION 構文 https://dev.mysql.com/doc/refman/5.6/ja/set-transaction.html POSTGRESQL: DOCUMENTATION: 11: 13.2. TRANSACTION ISOLATION HTTPS://WWW.POSTGRESQL.ORG/DOCS/11/TRANSACTION-ISO.HTML#MVCC-ISOLEVEL-TABLE Oracle Databaseの場合 Oracle Databaseでは、SERIALIZABLE と READ COMMITTED の分離レベルが用意されている。 READ COMMITEDには前提として、UNDOを使用した読取り一貫性の理解が必要。MVCC(MultiVersion Concurrency Control)という技術でありOracle Databaseは、UNDOデータを使用して一貫性を実現しています。 ユーザーがデータを変更すると、常にOracle DatabaseによってUNDOエントリが作成されて、UNDOセグメントに書き込まれる。UNDOセグメントには、未コミットのトランザクションや、最近コミットされたトランザクションによって変更されたデータの古い値が含まれている。このため、同じデータの異なる時点の複数のバージョンがデータベース内に存在することになる。 PostgreSQL/MySQLの場合 すべての分離レベルの利用が可能。 実装自体は各DBエンジン自体で異なり、PostgreSQLもMySQLのREPEATABLE READを選択した場合においても、Phantom Read は発生しない実装になっている模様。 13.2. トランザクションの分離 http://pgsql-jp.github.io/current/html/transaction-iso.html Write SkewをSERIALIZABLE分離レベルで試してみる 複数の並行に動作するトランザクションそれぞれの結果が、いかなる場合でも、それらのトランザクションを時間的重なりなく逐次実行した場合と同じ結果となる。 上記のSerializableに関して書かれたこの文章だけ何回読んでもよくわからないので、Serializableだけ実機で確認してみた。 変更方法 ・SET文を使用した指定方法(セッション単位) SET default_transaction_isolation TO '分離レベル'; ・SET文を使用した指定方法(トランザクション単位) SET TRANSACTION ISOLATION LEVEL 分離レベル; ・トランザクションの制御コマンドを使用した指定方法(トランザクション単位) トランザクションの開始時に指定 BEGIN ISOLATION LEVEL 分離レベル; START TRANSACTION ISOLATION LEVEL 分離レベル; 事前にテーブル/データ作成 drop table mytab; CREATE TABLE mytab ( class int NOT NULL, value int NOT NULL ); INSERT INTO mytab VALUES (1, 10), (1, 20), (2, 100), (2, 200); Session1 Session2 BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; SELECT SUM(value) FROM mytab WHERE class = 1; INSERT INTO mytab VALUES(2,30); BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; SELECT SUM(value) FROM mytab WHERE class = 2; INSERT INTO mytab VALUES (1, 300); commit; commit; BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; SELECT SUM(value) FROM mytab WHERE class = 1; INSERT INTO mytab VALUES (2, 330); COMMIT; SELECT * FROM mytab; Session1 aurorapostdb=> select * from mytab; class | value -------+------- 1 | 10 1 | 20 2 | 100 2 | 200 (4 rows) aurorapostdb=> aurorapostdb=> BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; BEGIN aurorapostdb=> SELECT SUM(value) FROM mytab WHERE class = 1; sum ----- 30 (1 row) aurorapostdb=> INSERT INTO mytab VALUES(2,30); INSERT 0 1 aurorapostdb=> Session2 aurorapostdb=> BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; BEGIN aurorapostdb=> SELECT SUM(value) FROM mytab WHERE class = 2; sum ----- 300 (1 row) aurorapostdb=> INSERT INTO mytab VALUES (1, 300); INSERT 0 1 aurorapostdb=> commit; COMMIT aurorapostdb=> Session1 #セッション2で実行 aurorapostdb=> commit; ERROR: could not serialize access due to read/write dependencies among transactions DETAIL: Reason code: Canceled on identification as a pivot, during commit attempt. HINT: The transaction might succeed if retried. aurorapostdb=> BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; BEGIN aurorapostdb=> SELECT SUM(value) FROM mytab WHERE class = 1; sum ----- 330 (1 row) aurorapostdb=> INSERT INTO mytab VALUES (2, 330); INSERT 0 1 aurorapostdb=> COMMIT; COMMIT aurorapostdb=> SELECT * FROM mytab; class | value -------+------- 1 | 10 1 | 20 2 | 100 2 | 200 1 | 300 2 | 330 (6 rows) aurorapostdb=> OracleとPostgreSQLのトランザクションの差異について OracleとPostgreSQLは同じRead Committedだが、トランザクションによっては違う結果になることを整理してみた OracleとPostgreSQLのトランザクション差異について整理する | my opinion is my own https://zatoima.github.io/oracle-postgresql-transaction-different.html 参照先、参考資料 データの同時実行性と整合性 https://docs.oracle.com/cd/E57425_01/121/CNCPT/consist.htm 第18回 ロックについて https://www.oracle.com/technetwork/jp/database/articles/tsushima/tsm18-1610822-ja.html SSI - PostgreSQL wiki https://wiki.postgresql.org/wiki/SSI postgresql isolation について - qiita https://qiita.com/kimullaa/items/ed12fa8f6cb993eee5cd ファントムリードは起こらないのにseirializableでない、それがポスグレのrepeatable read - qiita https://qiita.com/yuba/items/89496dda291edb2e558c --- ### OracleのパーティションテーブルをAurora(PostgreSQL)へSCT変換する場合の注意事項メモ date: 2019-11-15 url: https://zatoima.github.io/oracle-to-aws-sct-partition-limit.html tags: AWS, DMS, SCT こちらの記載に関する注意事項メモ。 Oracle から Amazon RDS for PostgreSQL または Amazon Aurora (PostgreSQL) への変換 - AWS Schema Conversion Tool https://docs.aws.amazon.com/ja_jp/SchemaConversionTool/latest/userguide/CHAP_Source.Oracle.ToPostgreSQL.html#CHAP_Source.Oracle.ToPostgreSQL.PG10Partitioning > 以下は、パーティションの PostgreSQL バージョン 10 への変換に関する既知の問題の一部です。 > NULL ではない列のみが列に分割することがでます。 > DEFAULT はパーティション値として使用できる値ではありません。 例えば、こういうレンジ・パーティションのテーブルがあったとして、ORDER_DATEをパーティション・キーとする。 drop table TAB_RANGE_PART; CREATE TABLE TAB_RANGE_PART ( ORDER_ID NUMBER primary key, ORDER_DATE DATE, BOOK_NO VARCHAR(20) NOT NULL, BOOK_TYPE VARCHAR(20) NOT NULL, BOOK_CNT NUMBER NOT NULL, REMARKS VARCHAR2(40)) LOGGING PCTFREE 20 PARTITION BY RANGE (ORDER_DATE) ( PARTITION TAB_RANGE_PART01 VALUES LESS THAN ( TO_DATE('20160101','YYYYMMDD')), PARTITION TAB_RANGE_PART02 VALUES LESS THAN ( TO_DATE('20170101','YYYYMMDD')), PARTITION TAB_RANGE_PART03 VALUES LESS THAN ( TO_DATE('20180101','YYYYMMDD')), PARTITION TAB_RANGE_PART04 VALUES LESS THAN ( TO_DATE('20190101','YYYYMMDD')), PARTITION TAB_RANGE_PART05 VALUES LESS THAN ( MAXVALUE )) ENABLE ROW MOVEMENT; **上記のDDLでは特にORDER_DATEに制約を設定していない**のでORDER_DATEにNullが入る可能性がある。この場合、SCTで変換した場合、エラーにもならず、パーティション・テーブルとして作成されない模様。下記の制限に該当する。 > NULL ではない列のみが列に分割することがでます。 こうなる。 既存のテーブルのパーティションキーに注意する必要あり。パーティションキーのORDER_DATEにNot Null制約を付与すればこうなる。 drop table TAB_RANGE_PART; CREATE TABLE TAB_RANGE_PART ( ORDER_ID NUMBER primary key, ORDER_DATE DATE NOT NULL, BOOK_NO VARCHAR(20) NOT NULL, BOOK_TYPE VARCHAR(20) NOT NULL, BOOK_CNT NUMBER NOT NULL, REMARKS VARCHAR2(40)) LOGGING PCTFREE 20 PARTITION BY RANGE (ORDER_DATE) ( PARTITION TAB_RANGE_PART01 VALUES LESS THAN ( TO_DATE('20160101','YYYYMMDD')), PARTITION TAB_RANGE_PART02 VALUES LESS THAN ( TO_DATE('20170101','YYYYMMDD')), PARTITION TAB_RANGE_PART03 VALUES LESS THAN ( TO_DATE('20180101','YYYYMMDD')), PARTITION TAB_RANGE_PART04 VALUES LESS THAN ( TO_DATE('20190101','YYYYMMDD')), PARTITION TAB_RANGE_PART05 VALUES LESS THAN ( MAXVALUE )) ENABLE ROW MOVEMENT; --- ### Aurora(PostgreSQL)でQPM(Query Plan Management)を試してみる date: 2019-11-13 url: https://zatoima.github.io/aurora-postgresql-query-plan-management.html tags: AWS, RDS, Aurora, PostgreSQL QPM(Query Plan Management)とは? SQLに実行計画を記録して、その実行計画を固定化、もしくは別環境に実行計画を移行して固定化出来る機能。Oracleで言うところのSPM(SQL Plan Management)になる。Aurora(PostgreSQL)でもこの機能が使えるので実際にやってみる。 Query Plan Managementの制御方法 rds.enable_plan_management = { 0,1} #パラメータグループで設定 apg_plan_mgmt.capture_plan_baselines = { manual, automatic, off } # automatic : 自動計画取り込み。1回以上実行されたSQLを取り込む # manual : 個々のSQLを手動で実行計画を取り込む # off : Query Planの取得を無効化 apg_plan_mgmt.use_plan_baselines = { true, false } # true : 取得したQuery Planを使用して実行計画を固定化する # false : 取得したQuery Planを使用しない。 環境、及びシナリオ説明 開発環境から本番環境への実行計画の移行を想定。 本番環境DB名:prod 開発環境DB名:dev 開発環境で実行したfull scan(seq scan)となる実行計画を本番環境に移行して非効率な実行計画を再現する。 パラメータグループ変更(dev/prod環境) クラスターパラメータグループの rds.enable_plan_management を1に設定 拡張機能の有効化(dev/prod環境) create extensionコマンドでapg_plan_mgmtをインストールする コマンド \dx create extension apg_plan_mgmt; \dx 実行結果 #実行結果 dev=> \dx List of installed extensions Name | Version | Schema | Description ---------+---------+------------+------------------------------ plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language (1 row) dev=> dev=> create extension apg_plan_mgmt; #拡張機能を有効化 CREATE EXTENSION dev=> \dx List of installed extensions Name | Version | Schema | Description ---------------+---------+---------------+-------------------------------------------------- ----------------- apg_plan_mgmt | 1.0.1 | apg_plan_mgmt | Amazon Aurora with PostgreSQL compatibility Query #★←apg_plan_mgmtが増えている Plan Management plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language (2 rows) dev=> dev=> dba_plans表の事前確認(dev/prod環境) apg_plan_mgmt.dba_plans表には当然何も格納されていない。 コマンド SELECT sql_hash, plan_hash, status, enabled, sql_text::varchar(100) FROM apg_plan_mgmt.dba_plans ORDER BY sql_text, plan_created; 実行結果 dev=> SELECT sql_hash, plan_hash, status, enabled, sql_text::varchar(100) dev-> FROM apg_plan_mgmt.dba_plans dev-> ORDER BY sql_text, plan_created; sql_hash | plan_hash | status | enabled | sql_text ----------+-----------+--------+---------+---------- (0 rows) テスト用のテーブル作成(dev/prod環境) テスト用のテーブルを作成する コマンド CREATE TABLE t1 AS SELECT num a -- 生成値 ,'1' b -- 定数 ,to_char(num,'FM00000') c -- 生成値を利用(IDなどの文字列) ,current_timestamp d FROM generate_series(1,10000) num ; ALTER TABLE t1 ADD PRIMARY KEY(a); \d t1 実行結果 dev=> CREATE TABLE t1 AS dev-> SELECT num a -- 生成値 dev-> ,'1' b -- 定数 dev-> ,to_char(num,'FM00000') c -- 生成値を利用(IDなどの文字列) dev-> ,current_timestamp d dev-> FROM generate_series(1,10000) num dev-> ; SELECT 10000 dev=> dev=> ALTER TABLE t1 ADD PRIMARY KEY(a); ALTER TABLE dev=> dev=> \d t1 Table "public.t1" Column | Type | Collation | Nullable | Default --------+--------------------------+-----------+----------+--------- a | integer | | not null | b | text | | | c | text | | | d | timestamp with time zone | | | Indexes: "t1_pkey" PRIMARY KEY, btree (a) dev=> SQLの実行、及び実行capture(dev環境) 実行計画が**full scan(seq scan)になるSQLと、Index ScanになるSQLを実行。この時、full scan(seq scan)**になるSQLの実行計画だけを手動で取り込む。 この例では「Plan Hash: -52705300」がapg_plan_mgmt.dba_plans表に取り込まれているのがわかる。 コマンド SET apg_plan_mgmt.capture_plan_baselines = manual; #実行計画の手動取り込みを有効化 explain (hashes true) select count(*) from t1 where a > 1; SET apg_plan_mgmt.capture_plan_baselines = off; #実行計画の手動取り込みを停止 explain (hashes true) select count(*) from t1 where a > 9999; SET apg_plan_mgmt.capture_plan_baselines = off; SELECT sql_hash, plan_hash, status, enabled, sql_text::varchar(100) FROM apg_plan_mgmt.dba_plans ORDER BY sql_text, plan_created; 実行結果 #実行ログ dev=> SET apg_plan_mgmt.capture_plan_baselines = manual; SET dev=> dev=> explain (hashes true) select count(*) from t1 where a > 1; QUERY PLAN -------------------------------------------------------------- Aggregate (cost=214.00..214.01 rows=1 width=8) -> Seq Scan on t1 (cost=0.00..189.00 rows=10000 width=0) Filter: (a > 1) SQL Hash: -1895827505, Plan Hash: -52705300 (4 rows) dev=> dev=> dev=> SET apg_plan_mgmt.capture_plan_baselines = off; SET dev=> dev=> dev=> dev=> explain (hashes true) select count(*) from t1 where a > 9999; QUERY PLAN ----------------------------------------------------------------------------- Aggregate (cost=8.30..8.31 rows=1 width=8) -> Index Only Scan using t1_pkey on t1 (cost=0.29..8.30 rows=1 width=0) Index Cond: (a > 9999) Plan Hash: 1222455040 (4 rows) dev=> dev=> SELECT sql_hash, plan_hash, status, enabled, sql_text::varchar(100) dev-> FROM apg_plan_mgmt.dba_plans dev-> ORDER BY sql_text, plan_created; sql_hash | plan_hash | status | enabled | sql_text -------------+-----------+----------+---------+-------------------------------------- -1895827505 | -52705300 | Approved | t | select count(*) from t1 where a > 1; #★←実行計画が取り込まれている (1 row) dev=> dev=> dev=> エクスポート用のテーブル作成(dev) CREATE TABLE plans_copy AS SELECT * FROM apg_plan_mgmt.plans; pg_dumpを使用してエクスポートする(dev) export PGPASSWORD=xxxxxx pg_dump -U postgres -h aurora-postgres-cluster-dev.cluster-xxxxxxxx.ap-northeast-1.rds.amazonaws.com -t plans_copy -Ft dev > plans_copy.tar #必要に応じて不要になった中間テーブルを削除する --DROP TABLE plans_copy; 別DBでインポート(prod) pg_restore -U postgres -h aurora-postgres-cluster-prod.cluster-xxxxxxxxx.ap-northeast-1.rds.amazonaws.com -t plans_copy -Ft plans_copy.tar -d prod インポート確認、及びマージ(prod) このあたりのマニュアルを参考に実行計画のマージを行います。 実行計画の維持 - Amazon Aurora https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Optimize.Maintenance.html#AuroraPostgreSQL.Optimize.Maintenance.ExportingImporting 計画のエクスポートおよびインポート コマンド INSERT INTO apg_plan_mgmt.plans SELECT * FROM plans_copy ON CONFLICT ON CONSTRAINT plans_pkey DO UPDATE SET status = EXCLUDED.status, enabled = EXCLUDED.enabled, last_used = CASE WHEN EXCLUDED.last_used > plans.last_used THEN EXCLUDED.last_used ELSE plans.last_used END, estimated_startup_cost = EXCLUDED.estimated_startup_cost, estimated_total_cost = EXCLUDED.estimated_total_cost, planning_time_ms = EXCLUDED.planning_time_ms, execution_time_ms = EXCLUDED.execution_time_ms, -- estimated_rows = EXCLUDED.estimated_rows, -- actual_rows = EXCLUDED.actual_rows, total_time_benefit_ms = EXCLUDED.total_time_benefit_ms, execution_time_benefit_ms = EXCLUDED.execution_time_benefit_ms; #管理計画を共有メモリにリロードする SELECT apg_plan_mgmt.reload(); -- refresh shared memory DROP TABLE plans_copy; -- 確認 SELECT sql_hash, plan_hash, status, enabled, sql_text::varchar(100) FROM apg_plan_mgmt.dba_plans ORDER BY sql_text, plan_created; この時、estimated_rows、actual_rowsをコメントアウトする必要あり。実際にはない行らしい。マニュアルの誤記? ERROR: column excluded.actual_rows does not exist LINE 13: actual_rows = EXCLUDED.actual_rows, 実行結果 prod=> INSERT INTO apg_plan_mgmt.plans SELECT * FROM plans_copy prod-> ON CONFLICT ON CONSTRAINT plans_pkey prod-> DO UPDATE SET prod-> status = EXCLUDED.status, prod-> enabled = EXCLUDED.enabled, prod-> last_used = CASE WHEN EXCLUDED.last_used > plans.last_used prod-> THEN EXCLUDED.last_used ELSE plans.last_used END, prod-> estimated_startup_cost = EXCLUDED.estimated_startup_cost, prod-> estimated_total_cost = EXCLUDED.estimated_total_cost, prod-> planning_time_ms = EXCLUDED.planning_time_ms, prod-> execution_time_ms = EXCLUDED.execution_time_ms, prod-> -- estimated_rows = EXCLUDED.estimated_rows, prod-> -- actual_rows = EXCLUDED.actual_rows, prod-> total_time_benefit_ms = EXCLUDED.total_time_benefit_ms, prod-> execution_time_benefit_ms = EXCLUDED.execution_time_benefit_ms; INSERT 0 2 prod=> prod=> prod=> SELECT apg_plan_mgmt.reload(); reload -------- 0 (1 row) prod=> prod=> prod=> DROP TABLE plans_copy; DROP TABLE prod=> prod=> prod=> prod=> prod=> SELECT sql_hash, plan_hash, status, enabled, sql_text::varchar(100) prod-> FROM apg_plan_mgmt.dba_plans prod-> ORDER BY sql_text, plan_created; sql_hash | plan_hash | status | enabled | sql_text -------------+------------+------------+---------+----------------------------------------- -1895827505 | -52705300 | Approved | t | select count(*) from t1 where a > 1; (2 rows) prod=> prod=> prod=> SQLの実行 今回はindex scanとなるところをfullscanを選択させているケース。 コマンド -- SQLのテスト SET apg_plan_mgmt.use_plan_baselines = true; explain (hashes true) select count(*) from t1 where a > 9999; SET apg_plan_mgmt.use_plan_baselines = false; 実行結果 prod=> SET apg_plan_mgmt.use_plan_baselines = true; prod=> prod=> explain (hashes true) select count(*) from t1 where a > 9999; QUERY PLAN --------------------------------------------------------------------------------- Aggregate (cost=189.00..189.01 rows=1 width=8) -> Seq Scan on t1 (cost=0.00..189.00 rows=1 width=0) Filter: (a > 9999) Note: An Approved plan was used instead of the minimum cost plan. SQL Hash: -1895827505, Plan Hash: -52705300, Minimum Cost Plan Hash: 1222455040 (5 rows) prod=> SET apg_plan_mgmt.use_plan_baselines = false; SET 今回の例ではwhere文でデータ取得件数を絞っているのでindex scanが実行プランとしては正しい。ただ、QPMでselect count(*) from t1 where a > 1;の実行計画が取り込まれており、この実行計画はFullscan(SeqScan)となる。敢えて非効率な実行計画を選択させたパターン。 実際にログ上にもNote: An Approved plan was used instead of the minimum cost plan.と記載がありもっとコストのよい実行計画があるぞーと言っている。 prod=> explain (hashes true) select count(*) from t1 where a > 9999; QUERY PLAN Aggregate (cost=189.00..189.01 rows=1 width=8) -> Seq Scan on t1 (cost=0.00..189.00 rows=1 width=0) Filter: (a > 9999) Note: An Approved plan was used instead of the minimum cost plan. SQL Hash: -1895827505, Plan Hash: -52705300, Minimum Cost Plan Hash: 1222455040 参考 実行計画の維持 - Amazon Aurora https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Optimize.Maintenance.html Amazon Aurora PostgreSQL でのクエリ計画管理のユースケース | Amazon Web Services ブログ https://aws.amazon.com/jp/blogs/news/use-cases-for-query-plan-management-in-amazon-aurora-postgresql/ --- ### Oracle Database 12.1.0.2にサンプルスキーマを手動インストール、手動作成する date: 2019-11-12 url: https://zatoima.github.io/oracle-install-sample-schema.html tags: Oracle はじめに やりたいことは表題の通り。検証作業をする時、自分で作るテスト用のテーブルだけではなくて、制約やトリガー、ビュー、本番相当(っぽい)データが入っているスキーマが欲しいなと思うことがよくある。Oracleのサンプル・スキーマのインストールはDBCA実行時に指定出来るが、チェック入れてないケースが多々 DBCA実行時にサンプル・スキーマのインストールを設定しておらず、後からサンプル・スキーマを作る方法をこちらに記載。今回は12.1.0.2で実行しましたが、おそらく12cR1以降であれば作成用スクリプトが用意されているので同じ手順で実行可能かと。 12.1.0.2用のスクリプトはこちら。 Release Oracle Database 12.1.0.2 Sample Schemas · oracle/db-sample-schemas · GitHub https://github.com/oracle/db-sample-schemas/releases/tag/v12.1.0.2 手順はこちら。 GitHub-oracle / db-sample-schemas:Oracle Databaseサンプルスキーマ https://github.com/oracle/db-sample-schemas なお、本日時点で12cR1~19c用のサンプルスキーマ作成用スクリプトがある。 事前準備 GitHubのソースコードをダウンロードして所定のディレクトリに配置する 12.1.0.2用のスクリプトはこちら。 Release Oracle Database 12.1.0.2 Sample Schemas · oracle/db-sample-schemas · GitHub https://github.com/oracle/db-sample-schemas/releases/tag/v12.1.0.2 db-sample-schemas-12.1.0.2.zipを$ORACLE_HOME/demo/schemaに展開。 unzip -q db-sample-schemas-12.1.0.2.zip -d /u01/app/oracle/product/12.1.0.2/dbhome_1/demo cd /u01/app/oracle/product/12.1.0.2/dbhome_1/demo/db-sample-schemas-12.1.0.2 ls -l [oracle@dbsrvec2 db-sample-schemas-12.1.0.2]$ ll 合計 100 -rw-r--r-- 1 oracle oinstall 117 11月 8 2015 CONTRIBUTING.md -rw-r--r-- 1 oracle oinstall 1050 11月 8 2015 LICENSE.md -rw-r--r-- 1 oracle oinstall 4986 11月 8 2015 README.md -rw-r--r-- 1 oracle oinstall 5263 11月 8 2015 README.txt drwxr-xr-x 2 oracle oinstall 85 11月 8 2015 bus_intelligence -rw-r--r-- 1 oracle oinstall 3633 11月 8 2015 drop_sch.sql drwxr-xr-x 2 oracle oinstall 197 11月 8 2015 human_resources drwxr-xr-x 2 oracle oinstall 79 11月 8 2015 info_exchange -rw-r--r-- 1 oracle oinstall 2740 11月 8 2015 mk_dir.sql -rw-r--r-- 1 oracle oinstall 28741 11月 8 2015 mkplug.sql -rw-r--r-- 1 oracle oinstall 7081 11月 8 2015 mksample.sql -rw-r--r-- 1 oracle oinstall 6592 11月 8 2015 mkunplug.sql -rw-r--r-- 1 oracle oinstall 6123 11月 8 2015 mkverify.sql drwxr-xr-x 3 oracle oinstall 4096 11月 8 2015 order_entry drwxr-xr-x 2 oracle oinstall 4096 11月 8 2015 product_media drwxr-xr-x 2 oracle oinstall 4096 11月 8 2015 sales_history drwxr-xr-x 2 oracle oinstall 186 11月 8 2015 shipping 実行コマンド スクリプトの一部修正 スクリプト内に埋め込んであるディレクトリを一部修正。ちなみにこのコマンド自体は↑の手順の中にある。 [oracle@dbsrvec2 schema]$ [oracle@dbsrvec2 schema]$ perl -p -i.bak -e 's#__SUB__CWD__#'$(pwd)'#g' *.sql */*.sql */*.dat mksample.sqlの実行 SYSTEM ユーザーのパスワード SYS ユーザーのパスワード HR ユーザーを作成し、設定する新しいパスワード OE ユーザーを作成し、設定する新しいパスワード PM ユーザーを作成し、設定する新しいパスワード IX ユーザーを作成し、設定する新しいパスワード SH ユーザーを作成し、設定する新しいパスワード BI ユーザーを作成し、設定する新しいパスワード デフォルト表領域 ※既に作成済みの表領域を指定。 一時表領域 ※既に作成済みの表領域を指定。 ログの出力先フォルダ ※フルパスで入力し、最後に「\」を付加します。 (例:/u01/app/oracle/product/12.1.0.2/dbhome_1/demo/schema/log/mksample/) 接続記述子を指定 実際のmksample.sql実行例 SQL> @mksample.sql [2019/11/12 13:04:11] specify password for SYSTEM as parameter 1: 1に値を入力してください: oracle [2019/11/12 13:04:13] specify password for SYS as parameter 2: 2に値を入力してください: oracle [2019/11/12 13:04:15] specify password for HR as parameter 3: 3に値を入力してください: oracle [2019/11/12 13:04:16] specify password for OE as parameter 4: 4に値を入力してください: oracle [2019/11/12 13:04:16] specify password for PM as parameter 5: 5に値を入力してください: oracle [2019/11/12 13:04:17] specify password for IX as parameter 6: 6に値を入力してください: oracle [2019/11/12 13:04:17] specify password for SH as parameter 7: 7に値を入力してください: oracle [2019/11/12 13:04:18] specify password for BI as parameter 8: 8に値を入力してください: oracle [2019/11/12 13:04:19] specify default tablespace as parameter 9: 9に値を入力してください: USERS [2019/11/12 13:04:24] specify temporary tablespace as parameter 10: 10に値を入力してください: TEMP [2019/11/12 13:04:25] specify log file directory (including trailing delimiter) as parameter 11: 11に値を入力してください: /u01/app/oracle/product/12.1.0.2/dbhome_1/demo/schema/log/mksample/ [2019/11/12 13:04:36] specify connect string as parameter 12: 12に値を入力してください: db121s Sample Schemas are being created ... [2019/11/12 13:04:39] 接続されました。 DROP USER hr CASCADE ~~中略~~ SH PRODUCTS_PROD_CAT_IX 5 72 SH PRODUCTS_PROD_STATUS_BIX 1 1 SH PRODUCTS_PROD_SUBCAT_IX 21 72 SH PROMO_PK 503 503 SH SALES_CHANNEL_BIX 4 92 SH SALES_CUST_BIX 7059 35808 SH SALES_PROD_BIX 72 1074 SH SALES_PROMO_BIX 4 54 SH SALES_TIME_BIX 1460 1460 SH SUP_TEXT_IDX SH TIMES_PK 1826 1826 72行が選択されました。 SQL> SQL> 作成確認 set pages 2000 lin 2000 col owner for a10 col object_type for a20 col COUNT(object_type) 999,999 SELECT owner, object_type, COUNT(object_type) FROM DBA_OBJECTS WHERE OWNER IN ('BI','SH','IX','PM','OE','HR') GROUP BY owner, object_type order by 1,2; OWNER OBJECT_TYPE COUNT(OBJECT_TYPE) ---------- -------------------- ------------------ BI SYNONYM 8 HR INDEX 19 HR PROCEDURE 2 HR SEQUENCE 3 HR TABLE 7 HR TRIGGER 2 HR VIEW 1 IX EVALUATION CONTEXT 2 IX INDEX 17 IX LOB 3 IX QUEUE 4 IX RULE SET 4 IX SEQUENCE 2 IX TABLE 17 IX TYPE 1 IX VIEW 8 OE FUNCTION 1 OE INDEX 48 OE LOB 15 OE SEQUENCE 1 OE SYNONYM 6 OE TABLE 14 OE TRIGGER 4 OE TYPE 37 OE TYPE BODY 3 OE VIEW 13 PM INDEX 21 PM LOB 17 PM TABLE 3 PM TYPE 3 SH DIMENSION 5 SH INDEX 30 SH INDEX PARTITION 196 SH LOB 2 SH MATERIALIZED VIEW 2 SH TABLE 17 SH TABLE PARTITION 56 SH VIEW 1 38行が選択されました。 SQL> Appendix こちらの方法でも良さそうだがやっていない。 Oracle Database 12cのサンプルスキーマ(HR, SH, OE…)をインストール - Qiita https://qiita.com/hobata/items/0bed0d1b2ed0566d2740 参考マニュアル サンプル・スキーマのインストール https://docs.oracle.com/cd/E82638_01/comsc/installing-sample-schemas.html#GUID-3800BD1C-E227-487E-ACD0-AD02BB03C03A --- ### Aurora(PostgreSQL)へのpsql接続時にパスワードを省略する方法 date: 2019-11-08 url: https://zatoima.github.io/aws-aurora-postgres-password.html tags: AWS, Aurora, PostgreSQL Aurora(PostgreSQL)ではなく、PostgreSQLのお話。 方法1: ‘.pgpass’ にパスワードを記載する ホームディレクトリに’.pgpass’ファイルを作成してこちらにパスワードを記載。 .pgpassの書式 ホスト名:ポート:データベース:ユーザ:パスワード 例)192.168.1.**:5432:dbname:dbuser:password .pgpassの作成 vi $HOME/.pgpass aurorapostdb.xxxxxxxxxx.ap-northeast-1.rds.amazonaws.com:5432:aurorapostdb:master:postgres chmod 600 $HOME/.pgpass [ec2-user@donald-dev-ec2-bastin ~]$ psql -h aurorapostdb.xxxxxxx.ap-northeast-1.rds.amazonaws.com -U master -d aurorapostdb psql (10.4, server 10.7) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) Type "help" for help. aurorapostdb=> 権限を変更しない場合、WARNINGが出る。 WARNING: password file “/home/ec2-user/.pgpass” has group or world access; permissions should be u=rw (0600) or less 方法2:環境変数に記載する export PGPASSWORD=postgres psql -h aurorapostdb.xxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -U master -d aurorapostdb [ec2-user@donald-dev-ec2-bastin ~]$ export PGPASSWORD=xxxxxxxx [ec2-user@donald-dev-ec2-bastin ~]$ psql -h aurorapostdb.xxxxxxx.ap-northeast-1.rds.amazonaws.com -U master -d aurorapostdb psql (10.4, server 10.7) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) Type "help" for help. aurorapostdb=> 参考 33.14. 環境変数 https://www.postgresql.jp/document/10/html/libpq-envars.html 33.15. パスワードファイル https://www.postgresql.jp/document/10/html/libpq-pgpass.html --- ### CloudWatchでDMSログを確認しようとすると「ロググループは存在しません」と出力される date: 2019-11-06 url: https://zatoima.github.io/aws-cloudwatchlogs-dms-log-error.html tags: AWS エラー内容 上記の右下の「ログの表示」ボタンをクリックした場合、CloudWatch Logsに移動しますが、移動後の画面でエラーが発生しました。 ロググループは存在しません ロググループ dms-tasks-dev-oracle-to-aurora-v2 が見つかりませんでした。このロググループが正しく作成されたことを確認し再試行してください。 エラー原因 上記に記載がありますが、こちらが原因となっていました。ログを確認するためには、下記が必要です。 dms-cloudwatch-logs-role IAM ロールが作成されていること 正しいアクセス許可ポリシーが設定されていること AWS DMS がロールを引き受けるための正しい信頼関係が設定されていること 普通は AWS DMS コンソールを使用して最初の AWS DMS タスクを作成したときに自動的に作成されるみたいです。 対応方法 下記のどちらかを参照して実行ください。 CloudWatch Logs が AWS DMS タスクに表示されない場合のトラブルシューティング https://aws.amazon.com/jp/premiumsupport/knowledge-center/dms-cloudwatch-logs-not-appearing/ AWS CLI と AWS DMS API で使用する IAM ロールを作成する - AWS DATABASE MIGRATION SERVICE HTTPS://DOCS.AWS.AMAZON.COM/JA_JP/DMS/LATEST/USERGUIDE/CHAP_SECURITY.APIROLE.HTML --- ### Aurora(PostgresSQL)のスロークエリログの出力方法 date: 2019-11-04 url: https://zatoima.github.io/aws-aurora-postgres-querylog.html tags: Aurora, RDS, PostgreSQL 1.バージョン確認 aurorapostdb=> select version(); version ----------------------------------------------------------------------------- PostgreSQL 10.7 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.9.3, 64-bit (1 row) 2.パラメータグループを変更 19.8. エラー報告とログ取得 https://www.postgresql.jp/document/10/html/runtime-config-logging.html log_statement=all #どのSQL文をログに記録するかを制御 log_min_duration_statement=0 #0に設定すれば、すべての文の実行時間が出力 log_destination=csvlog #csvlogがlog_destinationに含まれる場合、ログ項目はプログラムへの読み込みが簡便な"カンマ区切り値"書式(CSV)で出力 log_duration=1 log_error_verbosity=verbose #ログ取得されるそれぞれのメッセージに対し、サーバログに書き込まれる詳細の量を制御 3.Auroraを再起動する(パラメータの反映) 4.パラメータ確認 show log_statement; show log_min_duration_statement; show log_destination; show log_duration; show log_error_verbosity; 5.テスト用のクエリの実行 直積のSQLを実行 select count(*) from pg_tables a, pg_stats b, pg_index c, pg_locks d; 6.マネージメントコンソールから確認する error/postgresql.log.yyyy-mm-dd-hhmi.csv を確認 --- ### aws rds describe-db-snapshotsの結果をcsvとして出力 date: 2019-10-30 url: https://zatoima.github.io/aws-awscli-rds-descrive-db-snapshot.html tags: AWS, RDS jqコマンドの書式がググらないとわからない コマンド aws rds describe-db-snapshots --db-snapshot-identifier rdspostgresqldb-snapshot-test20191130-1 \ --query "DBSnapshots[].{DBInstanceIdentifier:DBInstanceIdentifier,DBSnapshotIdentifier:DBSnapshotIdentifier,SnapshotCreateTime:SnapshotCreateTime}" \ --output json | \ jq -r ".[] | [.DBInstanceIdentifier,.DBSnapshotIdentifier,.SnapshotCreateTime] | @csv" 結果 "rdspostgresqldb","rdspostgresqldb-snapshot-test20191130-1","2019-11-30T06:47:14.370Z" --- ### RDS(PostgreSQL)にsysbenchを実行する date: 2019-10-28 url: https://zatoima.github.io/aws-rds-postgresql-sysbench.html tags: AWS, RDS, PostgreSQL 前提事項 既に実行するOSにsysbenchがインストールされていることを前提とします。 EC2(Amazon Linux)にRDBMSベンチマークツールのsysbenchをインストールする - zato logger https://www.zatolog.com/entry/aws-ec2-sysbench-install-howto 事前準備 -- 接続 [ec2-user@donald-dev-ec2-bastin ~]$ psql -h aurora-postgressql-dev.cluster-xxxxxxxx.ap-northeast-1.rds.amazonaws.com -U postgres -d postdb Password for user postgres: psql (9.2.24, server 10.7) WARNING: psql version 9.2, server version 10.0. Some psql features might not work. SSL connection (cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256) Type "help" for help. postdb=> postdb=> -- ユーザ作成、権限付与、データベース作成 postdb=> CREATE USER sbtest WITH PASSWORD 'sbtest'; CREATE ROLE postdb=> postdb=> postdb=> postdb=> CREATE DATABASE sbtest; CREATE DATABASE postdb=> postdb=> GRANT ALL PRIVILEGES ON DATABASE sbtest TO sbtest; GRANT postdb=> postdb=> -- 作成したユーザで接続確認 [ec2-user@donald-dev-ec2-bastin ~]$ psql -h aurora-postgressql-dev.cluster-xxxxxxxxx.ap-northeast-1.rds.amazonaws.com -U sbtest -d sbtest Password for user sbtest: psql (9.2.24, server 10.7) WARNING: psql version 9.2, server version 10.0. Some psql features might not work. SSL connection (cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256) Type "help" for help. sbtest=> sbtest=> 測定用テーブルの作成 -- sysbench prepare [ec2-user@donald-dev-ec2-bastin ~]$ sysbench /usr/share/sysbench/oltp_read_write.lua --db-driver=pgsql --table-size=1000 --pgsql-host=aurora-postgressql-dev.cluster-xxxxxxxxxx.ap-northeast-1.rds.amazonaws.com --pgsql-user=sbtest --pgsql-password=sbtest --pgsql-db=sbtest --db-ps-mode=disable prepare sysbench 1.0.17 (using system LuaJIT 2.0.4) Creating table 'sbtest1'... Inserting 1000 records into 'sbtest1' Creating a secondary index on 'sbtest1'... [ec2-user@donald-dev-ec2-bastin ~]$ [ec2-user@donald-dev-ec2-bastin ~]$ 性能測定 -- sysbench run [ec2-user@donald-dev-ec2-bastin ~]$ sysbench /usr/share/sysbench/oltp_read_write.lua --db-driver=pgsql --table-size=1000 --pgsql-db=sbtest --pgsql-host=aurora-postgressql-dev.cluster-xxxxxxxxx.ap-northeast-1.rds.amazonaws.com --pgsql-user=sbtest --pgsql-password=sbtest --time=300 --db-ps-mode=disable --threads=16 run sysbench 1.0.17 (using system LuaJIT 2.0.4) Running the test with following options: Number of threads: 16 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 61096 write: 12922 other: 9695 total: 83713 transactions: 3125 (10.40 per sec.) queries: 83713 (278.61 per sec.) ignored errors: 1239 (4.12 per sec.) reconnects: 0 (0.00 per sec.) General statistics: total time: 300.4662s total number of events: 3125 Latency (ms): min: 10.53 avg: 1538.24 max: 19170.98 95th percentile: 6026.41 sum: 4807006.80 Threads fairness: events (avg/stddev): 195.3125/8.45 execution time (avg/stddev): 300.4379/0.02 [ec2-user@donald-dev-ec2-bastin ~]$ --- ### EC2(Amazon Linux)にRDBMSベンチマークツールのsysbenchをインストールする date: 2019-10-21 url: https://zatoima.github.io/aws-ec2-sysbench-install-howto.html tags: AWS, EC2 実行コマンド sysbench は EPEL のリポジトリに存在するので事前にインストールする必要がある。 sudo -s wget https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-7-12.noarch.rpm rpm -ivh epel-release-7-12.noarch.rpm yum -y install epel-release yum -y install sysbench 実行ログ [root@donald-dev-ec2-bastin ec2-user]# wget https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-7-12.noarch.rpm --2019-10-21 07:47:27-- https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-7-12.noarch.rpm Resolving dl.fedoraproject.org (dl.fedoraproject.org)... 209.132.181.25, 209.132.181.23, 209.132.181.24 Connecting to dl.fedoraproject.org (dl.fedoraproject.org)|209.132.181.25|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 15264 (15K) [application/x-rpm] Saving to: ‘epel-release-7-12.noarch.rpm’ 100%[==================================================================================================================================================>] 15,264 --.-K/s in 0.1s 2019-10-21 07:47:28 (119 KB/s) - ‘epel-release-7-12.noarch.rpm’ saved [15264/15264] [root@donald-dev-ec2-bastin ec2-user]# ll total 55692 -rw-r--r-- 1 root root 15264 Sep 18 12:56 epel-release-7-12.noarch.rpm -rw-rw-r-- 1 ec2-user ec2-user 4856388 Oct 16 02:34 function.zip -rw-r--r-- 1 root root 51434432 Oct 8 04:05 oracle-instantclient18.3-basic-18.3.0.0.0-3.x86_64.rpm -rw-r--r-- 1 root root 709700 Oct 8 04:08 oracle-instantclient18.3-sqlplus-18.3.0.0.0-3.x86_64.rpm drwxrwxr-x 3 ec2-user ec2-user 18 Oct 8 04:23 oradiag_ec2-user drwxrwxr-x 19 ec2-user ec2-user 4096 Oct 16 02:33 package drwxrwxr-x 3 ec2-user ec2-user 21 Oct 16 00:45 venv [root@donald-dev-ec2-bastin ec2-user]# [root@donald-dev-ec2-bastin ec2-user]# [root@donald-dev-ec2-bastin ec2-user]# [root@donald-dev-ec2-bastin ec2-user]# rpm -ivh epel-release-7-11.noarch.rpm error: open of epel-release-7-11.noarch.rpm failed: No such file or directory [root@donald-dev-ec2-bastin ec2-user]# [root@donald-dev-ec2-bastin ec2-user]# [root@donald-dev-ec2-bastin ec2-user]# [root@donald-dev-ec2-bastin ec2-user]# [root@donald-dev-ec2-bastin ec2-user]# rpm -ivh epel-release-7-12.noarch.rpm warning: epel-release-7-12.noarch.rpm: Header V3 RSA/SHA256 Signature, key ID 352c64e5: NOKEY Preparing... ################################# [100%] Updating / installing... 1:epel-release-7-12 ################################# [100%] [root@donald-dev-ec2-bastin ec2-user]# [root@donald-dev-ec2-bastin ec2-user]# [root@donald-dev-ec2-bastin ec2-user]# [root@donald-dev-ec2-bastin ec2-user]# [root@donald-dev-ec2-bastin ec2-user]# [root@donald-dev-ec2-bastin ec2-user]# yum -y install epel-release Loaded plugins: extras_suggestions, langpacks, priorities, update-motd epel/x86_64/metalink | 6.0 kB 00:00:00 epel | 5.4 kB 00:00:00 (1/3): epel/x86_64/group_gz | 90 kB 00:00:00 (2/3): epel/x86_64/updateinfo | 1.0 MB 00:00:00 (3/3): epel/x86_64/primary_db | 6.9 MB 00:00:00 186 packages excluded due to repository priority protections Package epel-release-7-12.noarch already installed and latest version Nothing to do [root@donald-dev-ec2-bastin ec2-user]# [root@donald-dev-ec2-bastin ec2-user]# [root@donald-dev-ec2-bastin ec2-user]# [root@donald-dev-ec2-bastin ec2-user]# yum -y install sysbench Loaded plugins: extras_suggestions, langpacks, priorities, update-motd 186 packages excluded due to repository priority protections Resolving Dependencies --> Running transaction check ---> Package sysbench.x86_64 0:1.0.17-2.el7 will be installed --> Processing Dependency: libck.so.0()(64bit) for package: sysbench-1.0.17-2.el7.x86_64 --> Processing Dependency: libluajit-5.1.so.2()(64bit) for package: sysbench-1.0.17-2.el7.x86_64 --> Running transaction check ---> Package ck.x86_64 0:0.5.2-2.el7 will be installed ---> Package luajit.x86_64 0:2.0.4-3.el7 will be installed --> Finished Dependency Resolution Dependencies Resolved ============================================================================================================================================================================================ Package Arch Version Repository Size ============================================================================================================================================================================================ Installing: sysbench x86_64 1.0.17-2.el7 epel 152 k Installing for dependencies: ck x86_64 0.5.2-2.el7 epel 26 k luajit x86_64 2.0.4-3.el7 epel 343 k Transaction Summary ============================================================================================================================================================================================ Install 1 Package (+2 Dependent packages) Total download size: 521 k Installed size: 1.7 M Downloading packages: warning: /var/cache/yum/x86_64/2/epel/packages/ck-0.5.2-2.el7.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 352c64e5: NOKEY Public key for ck-0.5.2-2.el7.x86_64.rpm is not installed (1/3): ck-0.5.2-2.el7.x86_64.rpm | 26 kB 00:00:00 (2/3): sysbench-1.0.17-2.el7.x86_64.rpm | 152 kB 00:00:00 (3/3): luajit-2.0.4-3.el7.x86_64.rpm | 343 kB 00:00:00 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Total 2.0 MB/s | 521 kB 00:00:00 Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 Importing GPG key 0x352C64E5: Userid : "Fedora EPEL (7) <epel@fedoraproject.org>" Fingerprint: 91e9 7d7c 4a5e 96f1 7f3e 888f 6a2f aea2 352c 64e5 Package : epel-release-7-12.noarch (installed) From : /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 Running transaction check Running transaction test Transaction test succeeded Running transaction Warning: RPMDB altered outside of yum. Installing : luajit-2.0.4-3.el7.x86_64 1/3 Installing : ck-0.5.2-2.el7.x86_64 2/3 Installing : sysbench-1.0.17-2.el7.x86_64 3/3 Verifying : ck-0.5.2-2.el7.x86_64 1/3 Verifying : sysbench-1.0.17-2.el7.x86_64 2/3 Verifying : luajit-2.0.4-3.el7.x86_64 3/3 Installed: sysbench.x86_64 0:1.0.17-2.el7 Dependency Installed: ck.x86_64 0:0.5.2-2.el7 luajit.x86_64 0:2.0.4-3.el7 Complete! [root@donald-dev-ec2-bastin ec2-user]# --- ### EC2インスタンスストアを使う場合はT2インスタンスタイプではダメ date: 2019-10-19 url: https://zatoima.github.io/aws-ec2-instancestore-setting.html tags: AWS, EC2 はじめに インスタンスストアは頻繁に変更される情報(バッファー、キャッシュ、スクラッチデータ、一時ログ、ダンプデータ、その他の一時コンテンツなど)の一時ストレージに適しています。追加料金は掛かりません。揮発性のディスクということでインスタンスを停止して起動するとデータが消えます。(再起動では消えません。) 勘違いしていたこと 表題の通りです。いつもよく使っていたインスタンスタイプ(t2系)はインスタンスストアが対応していないタイプでした。対応しているタイプは下記マニュアルに記載があります。 インスタンスで使用できるインスタンスストアボリュームの数とサイズは、インスタンスタイプによって異なります。インスタンスタイプによっては、インスタンスストアボリュームをサポートしていないものがあります。 EC2 インスタンスにインスタンスストアボリュームを追加する - Amazon Elastic Compute Cloud https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/add-instance-store-volumes.html インスタンスタイプにより、使用できるインスタンスストアのサイズ、およびインスタンスストアボリュームで使用されるハードウェアの種類が決まります。 Amazon EC2 インスタンスストア - Amazon Elastic Compute Cloud https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/InstanceStorage.html 下記のようにストレージ最適化のインスタンスタイプではインスタンス作成時のボリュームタイプにephemeral0が表示されています。これがインスタンスストアになります。 t2.large(汎用) i3.large(ストレージ最適化) インスタンスストアの設定/確認 インスタンスの起動後に、インスタンスストアボリュームはインスタンスで使用できますが、ボリュームがマウントされるまでアクセスすることはできません。Linux インスタンスの場合は、インスタンスタイプによって、どのインスタンスストアボリュームがマウントされるのか、またご自分でマウントできるインスタンスが何かが決まります。 初期状態 [ec2-user@ip-10-0-0-16 ~]$ df -h Filesystem Size Used Avail Use% Mounted on devtmpfs 7.5G 0 7.5G 0% /dev tmpfs 7.5G 0 7.5G 0% /dev/shm tmpfs 7.5G 464K 7.5G 1% /run tmpfs 7.5G 0 7.5G 0% /sys/fs/cgroup /dev/xvda1 8.0G 1.3G 6.8G 16% / tmpfs 1.5G 0 1.5G 0% /run/user/0 tmpfs 1.5G 0 1.5G 0% /run/user/1000 [ec2-user@ip-10-0-0-16 ~]$ ファイルシステム作成、及びマウント #コマンド mkfs.ext4 -E nodiscard /dev/nvme0n1 mkdir /mnt/ssd mount -o discard /dev/nvme0n1 /mnt/ssd #実行ログ [root@ip-10-0-0-16 ec2-user]# mkfs.ext4 -E nodiscard /dev/nvme0n1 mke2fs 1.42.9 (28-Dec-2013) Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) Stride=0 blocks, Stripe width=0 blocks 28999680 inodes, 115966796 blocks 5798339 blocks (5.00%) reserved for the super user First data block=0 Maximum filesystem blocks=2264924160 3540 block groups 32768 blocks per group, 32768 fragments per group 8192 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968, 102400000 Allocating group tables: done Writing inode tables: done Creating journal (32768 blocks): done Writing superblocks and filesystem accounting information: done [root@ip-10-0-0-16 ec2-user]# echo $? 0 [root@ip-10-0-0-16 ec2-user]# [root@ip-10-0-0-16 ec2-user]# [root@ip-10-0-0-16 ec2-user]# [root@ip-10-0-0-16 ec2-user]# mkdir /mnt/ssd [root@ip-10-0-0-16 ec2-user]# [root@ip-10-0-0-16 ec2-user]# [root@ip-10-0-0-16 ec2-user]# mount -o discard /dev/nvme0n1 /mnt/ssd [root@ip-10-0-0-16 ec2-user]# fstabに追記(再起動後にマウントされるように) vi /etc/fstab /dev/nvme0n1 /mnt/ssd ext4 defaults,nofail 0 2 確認 [root@ip-10-0-0-16 ec2-user]# df -h Filesystem Size Used Avail Use% Mounted on devtmpfs 7.5G 0 7.5G 0% /dev tmpfs 7.5G 0 7.5G 0% /dev/shm tmpfs 7.5G 464K 7.5G 1% /run tmpfs 7.5G 0 7.5G 0% /sys/fs/cgroup /dev/xvda1 8.0G 1.3G 6.8G 16% / tmpfs 1.5G 0 1.5G 0% /run/user/0 tmpfs 1.5G 0 1.5G 0% /run/user/1000 /dev/nvme0n1 436G 73M 414G 1% /mnt/ssd ★←インスタンスストア [root@ip-10-0-0-16 ec2-user]# 性能を比較してみる #インスタンスストア dd if=/dev/zero of=/mnt/ssd/write.tmp count=5 bs=1024M → 5368709120 bytes (5.4 GB) copied, 14.8873 s, 361 MB/s #EBS dd if=/dev/zero of=/home/ec2-user/write.tmp count=5 bs=1024M → 5368709120 bytes (5.4 GB) copied, 53.8642 s, 99.7 MB/s 使用するインスタンスタイプによって性能値が大きく異なる模様。 > インスタンスタイプによって SSD の性能が変わるのか調べてみた https://blog.manabusakai.com/2015/06/instance-store-benchmark/ その他注意事項 インスタンスを起動する場合にのみ、インスタンスのインスタンスストアボリュームを指定できます。また、起動後のインスタンスにインスタンスストアボリュームをアタッチすることはできません。 インスタンスタイプを変更すると、インスタンスストアは新しいインスタンスタイプにアタッチされません。 --- ### EC2(Amazon Linux)にpip、python3をインストール date: 2019-10-18 url: https://zatoima.github.io/aws-ec2-install-python3.html tags: Python, EC2 0.コマンド pip は Python 3.4 以降では Python 本体に同梱されるようなっているのでpip3の個別のインストールは不要。 sudo yum install -y python3 python3をインストール [postgres@postdb ~]$ sudo yum install python3 -y Loaded plugins: extras_suggestions, langpacks, priorities, update-motd amzn2-core | 2.4 kB 00:00:00 46 packages excluded due to repository priority protections Resolving Dependencies --> Running transaction check ---> Package python3.x86_64 0:3.7.6-1.amzn2.0.1 will be installed --> Processing Dependency: python3-libs(x86-64) = 3.7.6-1.amzn2.0.1 for package: python3-3.7.6-1.amzn2.0.1.x86_64 --> Processing Dependency: python3-setuptools for package: python3-3.7.6-1.amzn2.0.1.x86_64 --> Processing Dependency: python3-pip for package: python3-3.7.6-1.amzn2.0.1.x86_64 --> Processing Dependency: libpython3.7m.so.1.0()(64bit) for package: python3-3.7.6-1.amzn2.0.1.x86_64 --> Running transaction check ---> Package python3-libs.x86_64 0:3.7.6-1.amzn2.0.1 will be installed ---> Package python3-pip.noarch 0:9.0.3-1.amzn2.0.2 will be installed ---> Package python3-setuptools.noarch 0:38.4.0-3.amzn2.0.6 will be installed --> Finished Dependency Resolution Dependencies Resolved ============================================================================================================================================================================================ Package Arch Version Repository Size ============================================================================================================================================================================================ Installing: python3 x86_64 3.7.6-1.amzn2.0.1 amzn2-core 71 k Installing for dependencies: python3-libs x86_64 3.7.6-1.amzn2.0.1 amzn2-core 9.1 M python3-pip noarch 9.0.3-1.amzn2.0.2 amzn2-core 1.9 M python3-setuptools noarch 38.4.0-3.amzn2.0.6 amzn2-core 617 k Transaction Summary ============================================================================================================================================================================================ Install 1 Package (+3 Dependent packages) Total download size: 12 M Installed size: 50 M Downloading packages: (1/4): python3-3.7.6-1.amzn2.0.1.x86_64.rpm | 71 kB 00:00:00 (2/4): python3-libs-3.7.6-1.amzn2.0.1.x86_64.rpm | 9.1 MB 00:00:00 (3/4): python3-setuptools-38.4.0-3.amzn2.0.6.noarch.rpm | 617 kB 00:00:00 (4/4): python3-pip-9.0.3-1.amzn2.0.2.noarch.rpm | 1.9 MB 00:00:00 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Total 47 MB/s | 12 MB 00:00:00 Running transaction check Running transaction test Transaction test succeeded Running transaction Warning: RPMDB altered outside of yum. ** Found 1 pre-existing rpmdb problem(s), 'yum check' output follows: pgdg-redhat-repo-42.0-5.noarch has missing requires of /etc/redhat-release Installing : python3-pip-9.0.3-1.amzn2.0.2.noarch 1/4 Installing : python3-3.7.6-1.amzn2.0.1.x86_64 2/4 Installing : python3-setuptools-38.4.0-3.amzn2.0.6.noarch 3/4 Installing : python3-libs-3.7.6-1.amzn2.0.1.x86_64 4/4 Verifying : python3-setuptools-38.4.0-3.amzn2.0.6.noarch 1/4 Verifying : python3-pip-9.0.3-1.amzn2.0.2.noarch 2/4 Verifying : python3-3.7.6-1.amzn2.0.1.x86_64 3/4 Verifying : python3-libs-3.7.6-1.amzn2.0.1.x86_64 4/4 Installed: python3.x86_64 0:3.7.6-1.amzn2.0.1 Dependency Installed: python3-libs.x86_64 0:3.7.6-1.amzn2.0.1 python3-pip.noarch 0:9.0.3-1.amzn2.0.2 python3-setuptools.noarch 0:38.4.0-3.amzn2.0.6 Complete! [postgres@postdb ~]$ [postgres@postdb ~]$ pip3 --version pip 9.0.3 from /usr/lib/python3.7/site-packages (python 3.7) [postgres@postdb ~]$ [postgres@postdb ~]$ [postgres@postdb ~]$ python3 --version Python 3.7.6 [postgres@postdb ~]$ --- ### EC2上からpsqlでAurora(PostgreSQL)に接続するまで date: 2019-10-17 url: https://zatoima.github.io/aws-ec2-psql-install.html tags: AWS, EC2, RDS, Aurora, PostgreSQL EC2にpsqlをインストールし、その後構築済みのAurora(PostgreSQL)の環境に接続するまでをメモ。 実行コマンド sudo yum search postgresql sudo yum -y install postgresql.x86_64 psql -h <エンドポイント> -U <ユーザ名> -d <DB名> OS情報 [ec2-user@donald-dev-ec2-bastin ~]$ uname -a Linux donald-dev-ec2-bastin x.xx.xxx-xxx.xxx.amzn2.x86_64 #1 SMP Thu Aug 15 15:29:58 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux yum searchでPostgreSQL client programsを探す 実行結果からpostgresql.x86_64がPostgreSQL client programsと判明。 [ec2-user@donald-dev-ec2-bastin ~]$ sudo yum search postgresql Loaded plugins: extras_suggestions, langpacks, priorities, update-motd ================================================================================= N/S matched: postgresql ================================================================================== freeradius-postgresql.x86_64 : Postgresql support for freeradius pcp-pmda-postgresql.x86_64 : Performance Co-Pilot (PCP) metrics for PostgreSQL postgresql.x86_64 : PostgreSQL client programs postgresql-contrib.x86_64 : Extension modules distributed with PostgreSQL postgresql-devel.x86_64 : PostgreSQL development header files and libraries postgresql-docs.x86_64 : Extra documentation for PostgreSQL postgresql-jdbc.noarch : JDBC driver for PostgreSQL postgresql-jdbc-javadoc.noarch : API docs for postgresql-jdbc postgresql-libs.x86_64 : The shared libraries required for any PostgreSQL clients postgresql-libs.i686 : The shared libraries required for any PostgreSQL clients postgresql-odbc.x86_64 : PostgreSQL ODBC driver postgresql-plperl.x86_64 : The Perl procedural language for PostgreSQL postgresql-plpython.x86_64 : The Python2 procedural language for PostgreSQL postgresql-pltcl.x86_64 : The Tcl procedural language for PostgreSQL postgresql-server.x86_64 : The programs needed to create and run a PostgreSQL server postgresql-static.x86_64 : Statically linked PostgreSQL libraries postgresql-test.x86_64 : The test suite distributed with PostgreSQL postgresql-upgrade.x86_64 : Support for upgrading from the previous major release of PostgreSQL qt-postgresql.x86_64 : PostgreSQL driver for Qt's SQL classes qt-postgresql.i686 : PostgreSQL driver for Qt's SQL classes qt3-PostgreSQL.x86_64 : PostgreSQL drivers for Qt 3's SQL classes qt3-PostgreSQL.i686 : PostgreSQL drivers for Qt 3's SQL classes qt5-qtbase-postgresql.x86_64 : PostgreSQL driver for Qt5's SQL classes qt5-qtbase-postgresql.i686 : PostgreSQL driver for Qt5's SQL classes PyGreSQL.x86_64 : A Python client library for PostgreSQL apr-util-pgsql.x86_64 : APR utility library PostgreSQL DBD driver libdbi-dbd-pgsql.x86_64 : PostgreSQL plugin for libdbi perl-DBD-Pg.x86_64 : A PostgreSQL interface for perl php-pgsql.x86_64 : A PostgreSQL database module for PHP python-psycopg2.x86_64 : A PostgreSQL database adapter for Python python-psycopg2-debug.x86_64 : A PostgreSQL database adapter for Python 2 (debug build) python-psycopg2-doc.x86_64 : Documentation for psycopg python PostgreSQL database adapter redland-pgsql.x86_64 : PostgreSQL storage support for Redland rhdb-utils.x86_64 : Miscellaneous utilities for PostgreSQL - Red Hat Edition tcl-pgtcl.x86_64 : A Tcl client library for PostgreSQL Name and summary matches only, use "search all" for everything. [ec2-user@donald-dev-ec2-bastin ~]$ PostgreSQL client programsをインストール [ec2-user@donald-dev-ec2-bastin ~]$ sudo yum -y install postgresql.x86_64 Loaded plugins: extras_suggestions, langpacks, priorities, update-motd amzn2-core | 2.4 kB 00:00:00 Resolving Dependencies --> Running transaction check ---> Package postgresql.x86_64 0:9.2.24-1.amzn2.0.1 will be installed --> Processing Dependency: postgresql-libs(x86-64) = 9.2.24-1.amzn2.0.1 for package: postgresql-9.2.24-1.amzn2.0.1.x86_64 --> Processing Dependency: libpq.so.5()(64bit) for package: postgresql-9.2.24-1.amzn2.0.1.x86_64 --> Running transaction check ---> Package postgresql-libs.x86_64 0:9.2.24-1.amzn2.0.1 will be installed --> Finished Dependency Resolution Dependencies Resolved ============================================================================================================================================================================================ Package Arch Version Repository Size ============================================================================================================================================================================================ Installing: postgresql x86_64 9.2.24-1.amzn2.0.1 amzn2-core 3.0 M Installing for dependencies: postgresql-libs x86_64 9.2.24-1.amzn2.0.1 amzn2-core 235 k Transaction Summary ============================================================================================================================================================================================ Install 1 Package (+1 Dependent package) Total download size: 3.3 M Installed size: 17 M Downloading packages: (1/2): postgresql-libs-9.2.24-1.amzn2.0.1.x86_64.rpm | 235 kB 00:00:00 (2/2): postgresql-9.2.24-1.amzn2.0.1.x86_64.rpm | 3.0 MB 00:00:00 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Total 15 MB/s | 3.3 MB 00:00:00 Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : postgresql-libs-9.2.24-1.amzn2.0.1.x86_64 1/2 Installing : postgresql-9.2.24-1.amzn2.0.1.x86_64 2/2 Verifying : postgresql-9.2.24-1.amzn2.0.1.x86_64 1/2 Verifying : postgresql-libs-9.2.24-1.amzn2.0.1.x86_64 2/2 Installed: postgresql.x86_64 0:9.2.24-1.amzn2.0.1 Dependency Installed: postgresql-libs.x86_64 0:9.2.24-1.amzn2.0.1 Complete! [ec2-user@donald-dev-ec2-bastin ~]$ Aurora(PostgreSQL)へ接続 接続時にはセキュリティグループ等でEC2上の踏み台サーバからPostgreSQLへの接続を許可が必要。 [ec2-user@donald-dev-ec2-bastin ~]$ psql -h <エンドポイント> -U <ユーザ名> -d <DB名> Password for user master: psql (9.2.24, server 10.7) WARNING: psql version 9.2, server version 10.0. Some psql features might not work. SSL connection (cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256) Type "help" for help. aurorapostdb=> その他 EC2構築直後の状態で yum -y install postgresql.x86_64を行った場合、デフォルトのリポジトリを参照するのでpsqlのバージョンが古い。そういった場合は、手動でリポジトリを追加して任意のpsqlのバージョンをダウンロードすれば良い。 参考: EC2(Amazon Linux2)にPostgreSQLをインストールする | my opinion is my own https://zatoima.github.io/postgresql-ec2-insatll.html --- ### AWS CLIの初期設定(AWS認証情報設定) date: 2019-10-16 url: https://zatoima.github.io/aws-ec2-awscli-setting-credentials.html tags: AWS, EC2 IAMユーザーのアクセスキーを取得 事前にIAMのセキュリティ認証情報からAccess key IDとSecret access keyを取得します。 CLIの設定ファイル aws configureコマンドでAccess key IDとSecret access keyを設定します。 [ec2-user@donald-dev-ec2-bastin ~]$ aws configure AWS Access Key ID [None]: xxxxxxxxxxxxxxxxxxxxx AWS Secret Access Key [None]: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Default region name [None]: ap-northeast-1 Default output format [None]: text [ec2-user@donald-dev-ec2-bastin ~]$ [ec2-user@donald-dev-ec2-bastin ~]$ ls -l .aws total 8 -rw------- 1 ec2-user ec2-user 48 Oct 16 00:25 config -rw------- 1 ec2-user ec2-user 116 Oct 16 00:25 credentials [ec2-user@donald-dev-ec2-bastin ~]$ [ec2-user@donald-dev-ec2-bastin ~]$ cat .aws/config [default] output = text region = ap-northeast-1 [ec2-user@donald-dev-ec2-bastin ~]$ [ec2-user@donald-dev-ec2-bastin ~]$ cat .aws/credentials [default] aws_access_key_id = xxxxxxxxxxxxxxxxxxx aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxx [ec2-user@donald-dev-ec2-bastin ~]$ その他の設定方法 環境変数( AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN ) AWS認証情報ファイル( ~/.aws/credentials ) ★←今回の手順 CLI 設定ファイル( ~/.aws/config ) 認証情報 インスタンスプロファイルの認証情報(インスタンスに割り当てられたIAMロール) --- ### EC2上のRHEL上にOracle Database 12cR1をインストールする場合の事前準備 date: 2019-10-13 url: https://zatoima.github.io/aws-oracle-ec2-pre-install_1.html tags: AWS, EC2, Oracle はじめに 作業メモのようなものです。 前提事項 ECのインスタンスタイプはt2.large RHEL7.6にインストール CUIではなくGUIでインストールする runinstallerの実行までの手順 必要パッケージのインストール sudo -s export LANG=C yum -y install wget cd /etc/yum.repos.d wget https://public-yum.oracle.com/public-yum-ol7.repo curl -k https://public-yum.oracle.com/RPM-GPG-KEY-oracle-ol7 -o /etc/pki/rpm-gpg/RPM-GPG-KEY-oracle yum install oracle-rdbms-server-12cR1-preinstall ネットワーク、SELINUXの設定変更 vi /etc/sysconfig/network HOSTNAME=dbsrvec2 /etc/init.d/network restart cat /etc/selinux/config vi /etc/selinux/config SELINUX=disabled vi /etc/hosts x.xxx.181.3 dbsrvec2 グループ作成、及びユーザの設定変更 groupadd -g 54321 oinstall groupadd -g 1101 oper groupadd -g 1102 backupdba groupadd -g 1103 dgdba groupadd -g 1104 kmdba groupadd -g 1105 dba useradd -u 54321 -g oinstall -G oinstall,oper,backupdba,dgdba,kmdba,dba -d /home/oracle oracle usermod -u 54321 -g oinstall -G oinstall,oper,backupdba,dgdba,kmdba,dba oracle passwd oracle 必要なディレクトリの作成 mkdir -p /u01/app/oracle chown -R oracle:oinstall /u01/app/oracle chmod -R 775 /u01 cd /u01/app mkdir oraInventory chown oracle:oinstall oraInventory/ GUIでインストールするための設定 -- クライアント側(Windows側)にxmingをインストール ダウンロードファイル一覧 - Xming X Server for Windows - OSDN https://ja.osdn.net/projects/sfnet_xming/releases/ -- xorgをインストール yum -y install xorg-x11-xauth.x86_64 xorg-x11-server-utils.x86_64 -- xeyesで確認 yum -y install xeyes xeyes -- runinstaller/dbcaでxdpyinfoを使用するのでinstall yum -y install xdpyinfo スワップファイルの作成 sudo dd if=/dev/zero of=/swapfile bs=1G count=4 chmod 600 /swapfile mkswap /swapfile swapon /swapfile swapon -s vi /etc/fstab /swapfile swap swap defaults 0 0 runintallerの実行 ./runinstaller ~省略~ --- ### EC2上でruninstallerの実行エラー date: 2019-10-12 url: https://zatoima.github.io/aws-oracle-ec2-runinstaller-error.html tags: AWS, EC2, Oracle xclockやxeyesを使用できるように設定したにも関わらずruninstaller実行時にエラーになる。 設定した手順は下記の通り。 AWS EC2でX Window Systemをセットアップする - zato logger https://www.zatolog.com/entry/aws-ec2-xwindow [oracle@db121s-dev-ec2-oracle database]$ ./runInstaller Starting Oracle Universal Installer... Checking Temp space: must be greater than 500 MB. Actual 75212 MB Passed Checking swap space: 0 MB available, 150 MB required. Failed <<<< Checking monitor: must be configured to display at least 256 colors >>> Could not execute auto check for display colors using command /usr/bin/xdpyinfo. Check if the DISPLAY variable is set. Failed <<<< Some requirement checks failed. You must fulfill these requirements before continuing with the installation, Continue? (y/n) [n] y 理由1:Checking swap space: 0 MB available, 150 MB required. Failed «« 公式Linux AMIの初期構成にはswapパーティションが無いのでスワップ領域を設定する必要がある。 詳細は下記手順やマニュアルを参照。 Amazon EC2 インスタンスのスワップ領域としてメモリを割り当てるためのスワップファイルの使用 https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-memory-swap-file/ Amazon EC2(Linux)のswap領域ベストプラクティス | DevelopersIO https://dev.classmethod.jp/cloud/ec2linux-swap-bestpractice/ インスタンスストアスワップボリューム - Amazon Elastic Compute Cloud https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/instance-store-swap-volumes.html 理由2:Checking monitor: must be configured to display at least 256 colors »> Could not execute auto check for display colors using command /usr/bin/xdpyinfo. Check if the DISPLAY variable is set. Failed «« こちらはxdpyinfo自体がインストールされてなかったので、yumでインストール。「DISPLAY変数」と出たらXmingやサーバ側のX11転送の問題かと思いこんでいた…。xdpyinfoがインストールされていないだけという単純な問題 --- ### AWS EC2でX Window Systemをセットアップする date: 2019-10-10 url: https://zatoima.github.io/aws-ec2-xwindow.html tags: AWS, EC2, Oracle Oracle Databaseをインストール(DBCA)する際にX Window System環境が必要だったのでEC2上でXが動くように設定。EC上でX Window System環境を動作させるのは手間な印象があったが、いくつかのパッケージをyumでインストールするだけで実施が可能だった。 前提バージョン [ec2-user@bastin ~]$ cat /etc/os-release NAME="Amazon Linux" VERSION="2" ID="amzn" ID_LIKE="centos rhel fedora" VERSION_ID="2" PRETTY_NAME="Amazon Linux 2" ANSI_COLOR="0;33" CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2" HOME_URL="https://amazonlinux.com/" [ec2-user@bastin ~]$ cat /etc/image-id image_name="amzn2-ami-hvm" image_version="2" image_arch="x86_64" image_file="INCOMPLETE-amzn2-ami-hvm-2.0.20191116.0-x86_64.xfs.gpt" image_stamp="ec6f-62ed" image_date="20191118225945" recipe_name="amzn2 ami" recipe_id="cd573903-ca89-ecf8-cb7f-1320-48ba-1a6d-730da3c5" [ec2-user@bastin ~]$ クライアント側(Windows側)にxmingをインストール ダウンロードファイル一覧 - Xming X Server for Windows - OSDN https://ja.osdn.net/projects/sfnet_xming/releases/ xorg関連パッケージをインストール xorg-x11-xauth.x86_64 xorg-x11-server-utils.x86_64 sudo yum -y install xorg-x11-xauth.x86_64 xorg-x11-server-utils.x86_64 xeyesで確認 sudo yum -y install xeyes xeyes 補足 設定ファイル /etc/ssh/sshd_configの「X11Forwarding」がyesとなっているか SSHターミナルの設定 Teratermの場合 Teratermの[設定]-[SSH転送]にて「SSHポート転送」というウィンドウが表示されるので、その中の「Xクライアントアプリケーションの転送」にチェックを入れる。 Xshellの場合 X11Forwarding先を設定する ユーザ 実行ユーザにも注意(※ su or su - したユーザでは挙動が違った記憶が、、、、。曖昧。) --- ### EC2にOracle ClientをインストールしてRDS(Oracle)に接続する date: 2019-10-08 url: https://zatoima.github.io/oracle-ec2-oracleclient-install.html tags: AWS, EC2, Oracle 手順 1. Oracle Clientのbasicとsqlplusをインストール basic sudo -s #rpmファイルをcurlコマンドで取得 curl -o oracle-instantclient18.3-basic-18.3.0.0.0-3.x86_64.rpm http://yum.oracle.com/repo/OracleLinux/OL7/oracle/instantclient/x86_64/getPackage/oracle-instantclient18.3-basic-18.3.0.0.0-3.x86_64.rpm #rpmファイルをインストール yum -y localinstall oracle-instantclient18.3-basic-18.3.0.0.0-3.x86_64.rpm sqlplus sudo -s #rpmファイルをcurlコマンドで取得 curl -o oracle-instantclient18.3-sqlplus-18.3.0.0.0-3.x86_64.rpm http://yum.oracle.com/repo/OracleLinux/OL7/oracle/instantclient/x86_64/getPackage/oracle-instantclient18.3-sqlplus-18.3.0.0.0-3.x86_64.rpm #rpmファイルをインストール yum -y localinstall oracle-instantclient18.3-sqlplus-18.3.0.0.0-3.x86_64.rpm 環境変数の設定 export LD_LIBRARY_PATH=/usr/lib/oracle/18.3/client64/lib:$LD_LIBRARY_PATH export PATH=/usr/lib/oracle/18.3/client64/bin:$PATH 接続 #sqlplus 'user_name@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=dns_name)(PORT=port))(CONNECT_DATA=(SID=database_name)))' sqlplus 'oracle@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=db112s.cm678nkt5thr.ap-northeast-1.rds.amazonaws.com)(PORT=1521))(CONNECT_DATA=(SID=oradb)))' Oracle データベースエンジンを実行している DB インスタンスへの接続 - Amazon Relational Database Service https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_ConnectToOracleInstance.html 実行ログ [root@ip-10-0-0-170 ec2-user]# curl -o oracle-instantclient18.3-basic-18.3.0.0.0-3.x86_64.rpm http://yum.oracle.com/repo/OracleLinux/OL7/oracle/instantclient/x86_64/getPackage/oracle-instantclient18.3-basic-18.3.0.0.0-3.x86_64.rpm % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 49.0M 100 49.0M 0 0 16.1M 0 0:00:03 0:00:03 --:--:-- 16.1M [root@ip-10-0-0-170 ec2-user]# [root@ip-10-0-0-170 ec2-user]# yum -y localinstall oracle-instantclient18.3-basic-18.3.0.0.0-3.x86_64.rpm Loaded plugins: extras_suggestions, langpacks, priorities, update-motd Examining oracle-instantclient18.3-basic-18.3.0.0.0-3.x86_64.rpm: oracle-instantclient18.3-basic-18.3.0.0.0-3.x86_64 Marking oracle-instantclient18.3-basic-18.3.0.0.0-3.x86_64.rpm to be installed Resolving Dependencies --> Running transaction check ---> Package oracle-instantclient18.3-basic.x86_64 0:18.3.0.0.0-3 will be installed --> Finished Dependency Resolution amzn2-core/2/x86_64 | 2.4 kB 00:00:00 Dependencies Resolved ============================================================================================================================================================================================ Package Arch Version Repository Size ============================================================================================================================================================================================ Installing: oracle-instantclient18.3-basic x86_64 18.3.0.0.0-3 /oracle-instantclient18.3-basic-18.3.0.0.0-3.x86_64 220 M Transaction Summary ============================================================================================================================================================================================ Install 1 Package Total size: 220 M Installed size: 220 M Downloading packages: Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : oracle-instantclient18.3-basic-18.3.0.0.0-3.x86_64 1/1 Verifying : oracle-instantclient18.3-basic-18.3.0.0.0-3.x86_64 1/1 Installed: oracle-instantclient18.3-basic.x86_64 0:18.3.0.0.0-3 Complete! [root@ip-10-0-0-170 ec2-user]# [root@ip-10-0-0-170 ec2-user]# [root@ip-10-0-0-170 ec2-user]# [root@ip-10-0-0-170 ec2-user]# curl -o oracle-instantclient18.3-sqlplus-18.3.0.0.0-3.x86_64.rpm http://yum.oracle.com/repo/OracleLinux/OL7/oracle/instantclient/x86_64/getPackage/oracle-instantclient18.3-sqlplus-18.3.0.0.0-3.x86_64.rpm % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 693k 100 693k 0 0 379k 0 0:00:01 0:00:01 --:--:-- 379k [root@ip-10-0-0-170 ec2-user]# [root@ip-10-0-0-170 ec2-user]# [root@ip-10-0-0-170 ec2-user]# yum -y localinstall oracle-instantclient18.3-sqlplus-18.3.0.0.0-3.x86_64.rpm Loaded plugins: extras_suggestions, langpacks, priorities, update-motd Examining oracle-instantclient18.3-sqlplus-18.3.0.0.0-3.x86_64.rpm: oracle-instantclient18.3-sqlplus-18.3.0.0.0-3.x86_64 Marking oracle-instantclient18.3-sqlplus-18.3.0.0.0-3.x86_64.rpm to be installed Resolving Dependencies --> Running transaction check ---> Package oracle-instantclient18.3-sqlplus.x86_64 0:18.3.0.0.0-3 will be installed --> Finished Dependency Resolution Dependencies Resolved ============================================================================================================================================================================================ Package Arch Version Repository Size ============================================================================================================================================================================================ Installing: oracle-instantclient18.3-sqlplus x86_64 18.3.0.0.0-3 /oracle-instantclient18.3-sqlplus-18.3.0.0.0-3.x86_64 3.1 M Transaction Summary ============================================================================================================================================================================================ Install 1 Package Total size: 3.1 M Installed size: 3.1 M Downloading packages: Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : oracle-instantclient18.3-sqlplus-18.3.0.0.0-3.x86_64 1/1 Verifying : oracle-instantclient18.3-sqlplus-18.3.0.0.0-3.x86_64 1/1 Installed: oracle-instantclient18.3-sqlplus.x86_64 0:18.3.0.0.0-3 Complete! [root@ip-10-0-0-170 ec2-user]# [ec2-user@ip-10-0-0-170 ~]$ export LD_LIBRARY_PATH=/usr/lib/oracle/18.3/client64/lib:$LD_LIBRARY_PATH [ec2-user@ip-10-0-0-170 ~]$ [ec2-user@ip-10-0-0-170 ~]$ [ec2-user@ip-10-0-0-170 ~]$ export PATH=/usr/lib/oracle/18.3/client64/bin:$PATH [ec2-user@ip-10-0-0-170 ~]$ [ec2-user@ip-10-0-0-170 ~]$ sqlplus 'oracle@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=db112s.cm678nkt5thr.ap-northeast-1.rds.amazonaws.com)(PORT=1521))(CONNECT_DATA=(SID=oradb)))' SQL*Plus: Release 18.0.0.0.0 - Production on Tue Oct 8 04:30:33 2019 Version 18.3.0.0.0 Copyright (c) 1982, 2018, Oracle. All rights reserved. Enter password: Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production With the Partitioning, Oracle Label Security, OLAP, Data Mining and Real Application Testing options SQL> SQL> 参考 [Oracle Cloud][AWS] EC2にOracle ClientをインストールしてOCI Database(DBaaS)に接続してみた - IT Edge Blog https://itedge.stars.ne.jp/oracle-cloud-ec2-dbaas/ Oracle データベースエンジンを実行している DB インスタンスへの接続 - Amazon Relational Database Service https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_ConnectToOracleInstance.html --- ### AWS SysOps Administrator Associate 試験 不合格&合格体験記 date: 2019-09-16 url: https://zatoima.github.io/aws-sysops-certificate.html tags: AWS AWS 認定 SysOps アドミニストレーター – アソシエイトの不合格体験記、及び合格体験記です。失敗原因も書いて今後の反省材料にしたいと思います。もしこの記事を見る人があればこんなやつがいたんだな、と思い気を引き締めてください!! 前提 スキルレベル SAA(AWS 認定ソリューションアーキテクト – アソシエイト)は2017年に取得済です。個人的にはAWSは主に検証環境用途で使っていますが、業務ではたまに使う程度です。がっつり開発経験とかはありません。 試験前提 2018年の秋頃に試験内容が改訂されましたが、当然改訂後の試験を受験しました。(2019年9月に受験) 改訂前の試験(旧試験)は、「SAA(AWS 認定ソリューションアーキテクト – アソシエイト)を合格していればsysopsも簡単」、「Associate 3試験(Solution Architect、sysops、devops)の中では一番sysopsが簡単だった」というネット情報がありますが、鵜呑みにしないでください。僕みたいに不合格になります。 合格時と不合格時の結果 不合格の時の試験レポート 合格の時の試験レポート 試験範囲について まずは公式サイトを確認しましょう。 AWS 認定 SysOps アドミニストレーター – アソシエイト https://aws.amazon.com/jp/certification/certified-sysops-admin-associate/ 認定によって検証される能力 スケーラブルで、高可用性および高耐障害性を備えたシステムを AWS でデプロイ、管理、運用する AWS との間のデータフローを実装および制御する コンピューティング、データ、セキュリティ要件に基づく適切な AWS のサービスを選択する AWS 運用のベストプラクティスの適切な使用方法を識別する AWS の使用コストを予測し、運用コストコントロールメカニズムを識別する オンプレミスワークロードを AWS に移行する 推奨される知識 AWS の信条 (クラウドのアーキテクチャの設計) に関する理解 AWS CLI および SDK/API ツールの実践経験 AWS に関連するネットワーク技術の理解 セキュリティ概念の理解と、セキュリティコントロールとコンプライアンス要件の実装の実践経験 仮想化テクノロジーの理解 システムのモニタリングおよび監査経験 ネットワークの概念に関する知識 (DNS、TCP/IP、ファイアウォールなど) アーキテクチャの要件を解釈する能力 このページを見ても「で、何を勉強すればいいんや!」となるので、下記ページを見ましょう。一番まとまっています。(英語ですが、Google翻訳を使えばなんとかなります。) 一回不合格になった後に勉強方法を再度考える上で下記サイトを見つけました。 AWS Certified SysOps Administrator – Associate (SOA-C01) Exam Learning Path | Jayendra’s Blog http://jayendrapatil.com/aws-certified-sysops-administrator-associate-soa-c01-exam-learning-path/ 上記から個人的に大事なところを抽出したのが下記です。特に太字のところは重点的にやっていた方が良いと思います。 1.Monitoring & Management Tools CloudWatch AWS Config AWS Systems Manager Trusted Advisor Health Dashboard OpsWorks CloudFormation Beanstalk CloudTrail 2.Networking & Content Delivery VPC ELB CloudFront Route53 3.Compute EC2 Auto Scaling Lambda API Gateway 4.Storage S3 Glacier EBS Storage Gateway EFS Snowball 5.Databases RDS DynamoDB Aurora ElastiCache(Redis,Memcached) 6.Security IAM KMS 暗号化 Inspector Shield WAF Artifact 7.Integration Tools SQS SNS 8.Cost management Organizations Consolidated billing billing Alert とは言え、本当に満遍なく出題されるので上記のURLを参考に広く全般的に抑えていた方が良いです。1度目は受験に失敗しましたが、上記で言うところの細かいサービスの要点を抑えきれておらずに数%足りずに落ちました。 試験対策 参考にもならないレベルですが、基本的には1回目の受験は本当に適当でした。Blackbeltとよくある質問だけでいけるかな、と思っていました。 1回目の受験時 blackbeltを読み込む(メジャーなところのみ。上記で言うところの太字サービス) よくある質問を眺める sysopsの模擬試験 ここまでやって冒頭の通り、「SAA(AWS 認定ソリューションアーキテクト – アソシエイト)を合格していればsysopsも簡単」、「Associate 3試験(Solution Architect、sysops、devops)の中では一番sysopsが簡単だった」というネットの評判を見て試験へ突撃。(撃沈) 2回目の受験時 2回目の受験の時は主要サービスだけの理解では合格的に達するのは厳しいと思ったので幅広く勉強しました。 blackbeltを読み込む(基本的にすべて) よくある質問を眺める Udemy の模擬試験(2周) sysopsの模擬試験(2回目) 不安なところを実機を触って勉強する ちなみに驚きだったのが、AWSの模擬試験を1ヶ月あけて再度受験したところ問題が変わっていました。**ランダムで出題されるのか、もしくは模擬試験の入れ替えのタイミングだったのかは定かではありません**が、もしお金に余裕があるのであれば複数回受験しても良いかもしれません。 これから試験を受ける人へ向けて 油断せずにしっかり勉強しましょう。 幅広くサービスを理解しましょう 試験範囲は 公式サイト / Jayendra’s Blog http://jayendrapatil.com/aws-certified-sysops-administrator-associate-soa-c01-exam-learning-path/ を確認しましょう 所感 正直、1回目の受験の時は試験に受かりさえすればいいや、というモチベーションでやっていました。あまり意味のない受験ですね。一度落ちたので、それからサービス触り始めて理解しようと努めることができたのである意味良かったと思います。 資格試験の範囲をすべて業務で使うことは現実的には少ないと思うので、そういうところを如何に重点的に効率的にやるかが大事ですね。(特にAWS試験の場合は) あー、受かって良かった。次はdevopsかSAA Proを目指します! --- ### CIDR ネットマスクごとのアドレス数の簡易計算方法 date: 2019-09-01 url: https://zatoima.github.io/aws-vpc-cidr-ipaddress.html tags: AWS --- ### PostgreSQLのpg_hba.confのメモ date: 2019-08-27 url: https://zatoima.github.io/postgresql-about-pg-hba-conf.html tags: PostgreSQL 「pg_hba.conf」ファイルの書式 パターン1 : local データベース名 ユーザ名 認証方式 パターン2 : host データベース名 ユーザ名 IPアドレス サブネットマスク 認証方式 パターン3 : host データベース名 ユーザ名 CIDRアドレス 認証方式 接続方式 クライアントが認証する接続方式を指定 接続方式 内容 host TCP/IP接続 local UNIXドメイン接続 DB名 接続先のデータベース名を指定。複数を指定する場合はカンマ区切り。allは全てのデータベースが対象。 ユーザ名 接続するユーザ名を指定。複数を指定する場合はカンマ区切り。allは全てのユーザが対象。 IPアドレスとサブネット 接続方式が「host」の場合のみ。クライアントのIPアドレスの範囲を指定する。 クライアント認証の設定例 認証方式 内容 trust 常に許可 reject 常に拒否 md5 MD5で暗号化されたパスワード認証を行う password 暗号化されていない平文でのパスワード認証を行う その他 クライアント認証の判定はレコードの上から順に行われ、一致していればその行で指定されている方式で認証する。認証ができれば接続が許可され、認証できなければ接続は拒否される。認証に成功もしくは失敗した場合、次に続くレコードは確認しない。 --- ### クラウド環境(EC2など)への接続時へのタイムアウト対応 date: 2019-07-22 url: https://zatoima.github.io/aws-connect-timeout.html tags: AWS, EC2 --- ### MySQL5.7のmy.cnfのテンプレートを作成してみた date: 2019-07-20 url: https://zatoima.github.io/mysql-myconf-setting-template.html tags: MySQL MySQLのどのシステム変数をmy.cnfに指定するかを明示的にするためにテンプレートを作成しました。 要件や環境(メモリ値、ディレクトリ構成、ディスク性能(HDD or SSD))に応じて変更する部分が多々ありますのでご注意ください。 ※適宜追加、修正していく予定。 バージョン想定 MySQL 5.7 を想定しています。 mysql> select version(); +------------+ | version() | +------------+ | 5.7.26-log | +------------+ 1 row in set (0.00 sec) my.cnfテンプレート [mysqld] # 環境に応じてチューニングが必須 # ################# # Common # ################# # オートコミット機能を無効化 # init_connectで指定したSQL文はSUPER権限を持ったユーザに対しては実行されない init_connect='SET AUTOCOMMIT=0' # パスワードのチェックを無効化する validate-password=OFF # バイナリログを有効化 log-bin # サーバID server_id=1 # データディレクトリ datadir=/var/lib/mysql # ソケット・ファイル socket=/var/lib/mysql/mysql.sock # キャラクタセットの指定 character_set_server=utf8mb4 # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 # mysqld.logファイルの指定 log-error=/var/log/mysqld.log # mysqld.pidファイルの指定 pid-file=/var/run/mysqld/mysqld.pid # ################# # innodb # ################# # InnoDBデータファイルのパス innodb_data_file_path = ibdata1:1G:autoextend # InnoDBテーブルスペース自動拡張サイズ innodb_autoextend_increment = 64 # InnoDBのデータとインデックスをキャッシュするバッファのサイズ(推奨は物理メモリの8割) innodb_buffer_pool_size=300M # コミットされていないトランザクションのためのバッファのサイズ。innodb_buffer_pool_sizeの25%程度(最大でも64MB) # データインポート時やデータの洗替え時などは32M等に設定する innodb_log_buffer_size=8M # innodb_buffer_pool_sizeをいくつのインスタンスに分けるか指定。バッファサイズが大きい場合は分割することを推奨 # innodb_buffer_pool_instances=8 # InnoDBの更新ログを記録するディスク上のファイルサイズ(innodb_buffer_pool_sizeの4分の1程度) innodb_log_file_size=1G # データやインデックスを共有ではなくテーブル個別に保存する innodb_file_per_table=1 # OSのキャッシュをバイパスするかどうかを制御する # InnoDBとOSのファイルシステムキャッシュの両方にあるという「ダブルバッファリング」を防止するためにO_DIRECTを使用する innodb_flush_method=O_DIRECT # バッファプール上で変更されたデータをディスクに書き出す場合に、近隣のページをまとめて1回のI/Oで書き出す仕組み(SSDの場合は無効化が推奨) innodb_flush_neighbors=0 # 未コミットのトランザクション情報をキャッシュするメモリ上の領域。ラージトランザクションを実行してキャッシュから溢れて一時表を作成するケースにチューニングすることで有効 binlog_cache_size=32768 # 変更をREDOログに同期するタイミングを制御。ACIDが不要な場合に0 or 2を設定して高速化を図る。 innodb_flush_log_at_trx_commit=1 # ダブルライトバッファの無効化 # データインポート時のみ指定(通常時は指定しない) # skip_innodb_doublewrite # InnoDBの書込み要求に使用されるバックグラウンドスレッドの数 innodb_write_io_threads = 8 # InnoDBの読取り要求に使用されるバックグラウンドスレッドの数 innodb_read_io_threads = 8 # InnoDB で使用できる全体的な I/O容量(IOPS値が妥当)。SSD、HDDで変更すべき innodb_io_capacity=200 # innodb_io_capacity の変更に合わせて変更(設定しない場合、デフォルト値が innodb_io_capacity の 2 倍。下限2000) innodb_io_capacity_max=2000 # ################# # query cache # ################# # クエリキャッシュのブロックサイズ query_cache_min_res_unit=4096 # クエリキャッシュ最大サイズ query_cache_limit=16M # クエリキャッシュで使用するメモリサイズ query_cache_size=128M # クエリキャッシュのタイプ(0:off, 1:ON SELECT SQL_NO_CACHE以外, 2:DEMAND SELECT SQL_CACHEのみ) query_cache_type=2 # ################# # slow query log # ################# # スロークエリの出力設定 slow_query_log=ON # スロークエリと判定する秒数 long_query_time=3 # スロークエリログの場所(あらかじめ作成しておく必要あり) slow_query_log_file=/var/log/slow.log # ################# # replication # ################# # GTID有効 gtid_mode=on # GTID利用時に必須となる設定(GTIDの一貫性を担保できないSQLの実行を禁止) enforce_gtid_consistency=on # ################# # thread buffer # ################# # インデックス未使用でのJOIN時に使用するバッファ join_buffer_size=256K # フルスキャンのレコードバッファ read_buffer_size=1M # ソート時に使用されるバッファ sort_buffer_size=4M # キーを使用したソートで読み込まれた行がキャッシュされるバッファ read_rnd_buffer_size=2M # ################# # etc # ################# # クライアントからサーバーに送信できるパケットの最大長 max_allowed_packet=8M # MEMORYテーブルの最大サイズ。このサイズを超えたMEMORYテーブルはディスク上に作成 max_heap_table_size=16M # スレッド毎に作成される一時的なテーブルの最大サイズ。スレッドバッファ tmp_table_size=16M # スレッドキャッシュ保持最大数 thread_cache_size=100 # コネクションタイムアウト時間 wait_timeout=30 # テーブルキャッシュ値。本値を変更する際はopen_files_limitも合わせて引き上げる必要がある。 # open_files_limitはOS側がmysqldプロセスに対して許可するファイルディスクリプタ上限を制御。 table_open_cache=2000 # テーブル定義キャッシュ。テーブル定義(.frmファイル)をキャッシュし、テーブルをオープンする際に高速化 table_definition_cache=1400 # 送受信するパケットを格納するパケットメッセージバッファサイズの初期値 net_buffer_length=16384 参考 参考ブログ1 (帰ってきた)InnoDBパフォーマンス最適化の基礎 | Yakst https://yakst.com/ja/posts/65 参考ブログ2 MySQLをインストールしたら、必ず確認すべき10の設定 | Yakst https://yakst.com/ja/posts/200 参考ブログ3 MySQL関連のパラメータ(主にInnoDB)について - hiroi10のブログ http://hiroi10.hatenablog.com/entry/20151210/1449731029 参考書籍1 [asin:4774170208:detail] 参考書籍2 [asin:B01N0R2BL2:detail] --- ### MySQLのInnoDB バッファープールのプリロード date: 2019-07-19 url: https://zatoima.github.io/mysql-buffer-pool-load.html tags: MySQL はじめに MySQLのバッファープールのプリロード機能について整理する。※Oracleにはない機能なので気になった 関連するシステム変数 mysql> select version(); +------------+ | version() | +------------+ | 5.7.26-log | +------------+ 1 row in set (0.00 sec) mysql> mysql> show variables like 'innodb_buffer_pool%'; +-------------------------------------+----------------+ | Variable_name | Value | +-------------------------------------+----------------+ | innodb_buffer_pool_chunk_size | 134217728 | | innodb_buffer_pool_dump_at_shutdown | ON | | innodb_buffer_pool_dump_now | OFF | | innodb_buffer_pool_dump_pct | 25 | | innodb_buffer_pool_filename | ib_buffer_pool | | innodb_buffer_pool_instances | 1 | | innodb_buffer_pool_load_abort | OFF | | innodb_buffer_pool_load_at_startup | ON | | innodb_buffer_pool_load_now | OFF | | innodb_buffer_pool_size | 134217728 | +-------------------------------------+----------------+ 10 rows in set (0.00 sec) innodb_buffer_pool_dump_at_shutdown シャットダウン時にバッファプール上のキャッシュを保持するかどうか。 https://dev.mysql.com/doc/refman/5.6/ja/innodb-parameters.html#sysvar_innodb_buffer_pool_dump_at_shutdown 次回再起動時のウォームアッププロセスの時間を短縮するために、MySQL サーバーのシャットダウン時に、InnoDB のバッファープールにキャッシュされるページを記録するかどうかを指定します。一般に、innodb_buffer_pool_load_at_startup と組み合わせて使用されます。 シャットダウン後に ib_buffer_pool が作成されている。 [mysql@awsstg-db001 mysql]$ ls -l ib_buffer_pool -rw-r----- 1 mysql mysql 3206 Jun 29 15:07 ib_buffer_pool [mysql@awsstg-db001 mysql]$ このパラメータを設定することでシャットダウンシーケンス時にはエラーログに下記のログが出力される。 2019-06-27T07:59:52.431613Z 0 [Note] InnoDB: Starting shutdown... 2019-06-27T07:59:52.531945Z 0 [Note] InnoDB: Dumping buffer pool(s) to /var/lib/mysql/ib_buffer_pool 2019-06-27T07:59:52.532242Z 0 [Note] InnoDB: Buffer pool(s) dump completed at 190627 7:59:52 2019-06-27T07:59:54.242932Z 0 [Note] InnoDB: Shutdown completed; log sequence number 616413821 innodb_buffer_pool_load_at_startup スタートアップ時に ib_buffer_pool を読み込んでバッファプールにプリロードを行う。 https://dev.mysql.com/doc/refman/5.6/ja/innodb-parameters.html#sysvar_innodb_buffer_pool_load_at_startup MySQL サーバーの起動時に、以前に保持されたときと同じページをロードすることで、InnoDB のバッファープールが自動的にウォームアップされるように指定します。一般に、innodb_buffer_pool_dump_at_shutdown と組み合わせて使用されます。 innodb_buffer_pool_filename 記録するファイル名を指定 innodb_buffer_pool_dump_now/innodb_buffer_pool_load_at_startup シャットダウンやスタートアップ時ではなくMySQLがオンライン時に任意のタイミングで即時書き出し、及び即時読み込みを行う。 ib_buffer_poolに保存される情報 必要なテーブルスペース ID と ページ ID [mysql@awsstg-db001 mysql]$ head ib_buffer_pool 0,890 0,889 0,888 0,887 0,886 0,885 0,884 0,883 0,882 0,881 該当するページを見つけるために必要なテーブルスペース ID とページ ID だけがディスクに保存されます。この情報は、INNODB_BUFFER_PAGE_LRU INFORMATION_SCHEMA テーブルから取得されます。デフォルトでは、テーブルスペース ID とページ ID のデータは、InnoDB データディレクトリに保存される ib_buffer_pool という名前のファイル内に保存されます。このファイル名は、innodb_buffer_pool_filename 構成パラメータを使用して変更できます。 この情報は INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU から取得される模様。 mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU LIMIT 1\G *************************** 1. row *************************** POOL_ID: 0 LRU_POSITION: 0 SPACE: 30 PAGE_NUMBER: 11063 PAGE_TYPE: INDEX FLUSH_TYPE: 0 FIX_COUNT: 0 IS_HASHED: NO NEWEST_MODIFICATION: 0 OLDEST_MODIFICATION: 0 ACCESS_TIME: 2747830684 TABLE_NAME: `mydb`.`t1` INDEX_NAME: PRIMARY NUMBER_RECORDS: 648 DATA_SIZE: 14904 COMPRESSED_SIZE: 0 COMPRESSED: NO IO_FIX: IO_NONE IS_OLD: YES FREE_PAGE_CLOCK: 0 1 row in set (0.01 sec) --- ### MySQLのバイナリログを確認してみた date: 2019-07-18 url: https://zatoima.github.io/mysql-binlog-show.html tags: MySQL バイナリログを確認 実行コマンド -- login mysql -u myuser -pmysql -- 既存のバイナリログを確認、及びバイナリログのスイッチ show binary logs; flush binary logs; show binary logs; -- バイナリログを確認 -- この時にはバイナリのログの中には何も更新情報はない show binlog events in 'awsstg-db001-bin.000011'; show variables like 'binlog_format'; use mydb; desc t1; insert into t1 values(1,'1度目のInsert','testテスト',5555,now()); -- バイナリログを確認 -- 上記Insertが記録されている show binlog events in 'awsstg-db001-bin.000011'; -- binlog_formatを変更した後に実行 show variables like 'binlog_format'; set session binlog_format='STATEMENT'; show variables like 'binlog_format'; insert into t1 values(2,'2度目のInsert','testテスト',5555,now()); show binlog events in 'awsstg-db001-bin.000011'; 実行結果 [ec2-user@awsstg-db001 ~]$ [ec2-user@awsstg-db001 ~]$ [ec2-user@awsstg-db001 ~]$ [ec2-user@awsstg-db001 ~]$ mysql -u myuser -pmysql mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 15 Server version: 5.7.26-log MySQL Community Server (GPL) Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> mysql> show binary logs; +-------------------------+-----------+ | Log_name | File_size | +-------------------------+-----------+ | awsstg-db001-bin.000001 | 42128655 | | awsstg-db001-bin.000002 | 217 | | awsstg-db001-bin.000003 | 3533 | | awsstg-db001-bin.000004 | 217 | | awsstg-db001-bin.000005 | 217 | | awsstg-db001-bin.000006 | 1164 | | awsstg-db001-bin.000007 | 84251908 | | awsstg-db001-bin.000008 | 1270 | | awsstg-db001-bin.000009 | 248 | | awsstg-db001-bin.000010 | 194 | +-------------------------+-----------+ 10 rows in set (0.00 sec) mysql> flush binary logs; Query OK, 0 rows affected (0.01 sec) mysql> show binary logs; +-------------------------+-----------+ | Log_name | File_size | +-------------------------+-----------+ | awsstg-db001-bin.000001 | 42128655 | | awsstg-db001-bin.000002 | 217 | | awsstg-db001-bin.000003 | 3533 | | awsstg-db001-bin.000004 | 217 | | awsstg-db001-bin.000005 | 217 | | awsstg-db001-bin.000006 | 1164 | | awsstg-db001-bin.000007 | 84251908 | | awsstg-db001-bin.000008 | 1270 | | awsstg-db001-bin.000009 | 248 | | awsstg-db001-bin.000010 | 248 | | awsstg-db001-bin.000011 | 194 | +-------------------------+-----------+ 11 rows in set (0.00 sec) mysql> mysql> show binlog events in 'awsstg-db001-bin.000011'; +-------------------------+-----+----------------+-----------+-------------+-------------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +-------------------------+-----+----------------+-----------+-------------+-------------------------------------------+ | awsstg-db001-bin.000011 | 4 | Format_desc | 1 | 123 | Server ver: 5.7.26-log, Binlog ver: 4 | | awsstg-db001-bin.000011 | 123 | Previous_gtids | 1 | 194 | 86a2b2da-9683-11e9-9dd6-067b425ce144:1-72 | +-------------------------+-----+----------------+-----------+-------------+-------------------------------------------+ 2 rows in set (0.00 sec) mysql> show variables like 'binlog_format'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | binlog_format | ROW | +---------------+-------+ 1 row in set (0.00 sec) mysql> mysql> use mydb; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> desc t1 -> ; +-------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+------------------+------+-----+---------+----------------+ | a | int(11) | NO | PRI | NULL | auto_increment | | b | varchar(10) | YES | | NULL | | | c | varchar(30) | YES | | NULL | | | d | int(10) unsigned | YES | | NULL | | | e | datetime | YES | | NULL | | +-------+------------------+------+-----+---------+----------------+ 5 rows in set (0.00 sec) mysql> mysql> insert into t1 values(1,'1度目のInsert','testテスト',5555,now()); Query OK, 1 row affected (0.00 sec) mysql> mysql> show binlog events in 'awsstg-db001-bin.000011'; +-------------------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +-------------------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+ | awsstg-db001-bin.000011 | 4 | Format_desc | 1 | 123 | Server ver: 5.7.26-log, Binlog ver: 4 | | awsstg-db001-bin.000011 | 123 | Previous_gtids | 1 | 194 | 86a2b2da-9683-11e9-9dd6-067b425ce144:1-72 | | awsstg-db001-bin.000011 | 194 | Gtid | 1 | 259 | SET @@SESSION.GTID_NEXT= '86a2b2da-9683-11e9-9dd6-067b425ce144:73' | | awsstg-db001-bin.000011 | 259 | Query | 1 | 339 | BEGIN | | awsstg-db001-bin.000011 | 339 | Table_map | 1 | 393 | table_id: 110 (mydb.t1) | | awsstg-db001-bin.000011 | 393 | Write_rows | 1 | 473 | table_id: 110 flags: STMT_END_F | | awsstg-db001-bin.000011 | 473 | Xid | 1 | 504 | COMMIT /* xid=178 */ | +-------------------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+ 7 rows in set (0.00 sec) mysql> show variables like 'binlog_format'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | binlog_format | ROW | +---------------+-------+ 1 row in set (0.01 sec) mysql> set session binlog_format='STATEMENT'; Query OK, 0 rows affected (0.00 sec) mysql> show variables like 'binlog_format'; +---------------+-----------+ | Variable_name | Value | +---------------+-----------+ | binlog_format | STATEMENT | +---------------+-----------+ 1 row in set (0.01 sec) mysql> insert into t1 values(2,'2度目のInsert','testテスト',5555,now()); Query OK, 1 row affected (0.00 sec) mysql> mysql> mysql> show binlog events in 'awsstg-db001-bin.000011'; +-------------------------+-----+----------------+-----------+-------------+------------------------------------------------------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +-------------------------+-----+----------------+-----------+-------------+------------------------------------------------------------------------------------+ | awsstg-db001-bin.000011 | 4 | Format_desc | 1 | 123 | Server ver: 5.7.26-log, Binlog ver: 4 | | awsstg-db001-bin.000011 | 123 | Previous_gtids | 1 | 194 | 86a2b2da-9683-11e9-9dd6-067b425ce144:1-72 | | awsstg-db001-bin.000011 | 194 | Gtid | 1 | 259 | SET @@SESSION.GTID_NEXT= '86a2b2da-9683-11e9-9dd6-067b425ce144:73' | | awsstg-db001-bin.000011 | 259 | Query | 1 | 339 | BEGIN | | awsstg-db001-bin.000011 | 339 | Table_map | 1 | 393 | table_id: 110 (mydb.t1) | | awsstg-db001-bin.000011 | 393 | Write_rows | 1 | 473 | table_id: 110 flags: STMT_END_F | | awsstg-db001-bin.000011 | 473 | Xid | 1 | 504 | COMMIT /* xid=178 */ | | awsstg-db001-bin.000011 | 504 | Gtid | 1 | 569 | SET @@SESSION.GTID_NEXT= '86a2b2da-9683-11e9-9dd6-067b425ce144:74' | | awsstg-db001-bin.000011 | 569 | Query | 1 | 656 | BEGIN | | awsstg-db001-bin.000011 | 656 | Query | 1 | 808 | use `mydb`; insert into t1 values(2,'2度目のInsert','testテスト',5555,now()) | | awsstg-db001-bin.000011 | 808 | Xid | 1 | 839 | COMMIT /* xid=183 */ | +-------------------------+-----+----------------+-----------+-------------+------------------------------------------------------------------------------------+ 11 rows in set (0.00 sec) mysql> --- ### MySQLクライアントのパスワード指定でスペースを入れてはいけない理由 date: 2019-07-17 url: https://zatoima.github.io/mysql-password-space.html tags: MySQL パスワード指定でスペースを入れたらダメ MySQLにログインする場合、mysql -u root -p<パスワード> というコマンドでログインすると思います。-pの後ろにスペースを入れてしまい、エラー(もしくはパスワードを求められる)になるというケースが幾度となくありました。スペースを入れてはいけない理由を改めてマニュアルから確認しました。 MySQL :: MySQL 5.6 リファレンスマニュアル :: 4.2.4 コマンド行でのオプションの使用 https://dev.mysql.com/doc/refman/5.6/ja/command-line-options.html パスワードオプションは、短い形式で -p*pass_val* または -p としても指定できます。しかし短い形式の場合、パスワード値を指定する場合は、間にスペースを入れずにオプション文字に続けなければいけません。この理由は、オプション文字にスペースが続く場合、続く引数がパスワード値なのかほかの種類の引数なのかをプログラムが判断する方法がないためです。 ここに記載がありますね。スペースを空けてしまうと指定されたパスワードが本当にパスワードなのか他の種類のオプション引数なのかを判別出来ないので厳格にスペースを許可していないとのことでした。 スペースを空けずにパスワードを指定(正しい指定方法) 正常にログインが出来ます。 [root@awsstg-db002 mysql]# mysql -u root -pmysql mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 18 Server version: 5.7.26-log MySQL Community Server (GPL) Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> スペースを空けてパスワードを指定(誤った指定方法) Enter password:とコンソールに出力されている通り、指定したはずのmysqlというパスワードが認識されていません。ログイン後にstatusコマンドでどこのデータベースにログインしているか確認してみると「mysql」データベースに接続されています。 パスワードを打ったと思ったmysqlがログインするデータベース名と認識されています。 ※そもそもですがパスワードにmysqlとか使うのはやめましょう。あとワーニングにも出力されていますが、ログイン時にパスワードを直書きするのもやめましょう。historyコマンドなどでパスワードがわかってしまいセキュリティ的によくありません。 mysql: [Warning] Using a password on the command line interface can be insecure. [root@awsstg-db002 mysql]# mysql -u root -p mysql Enter password: Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 15 Server version: 5.7.26-log MySQL Community Server (GPL) Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> status -------------- mysql Ver 14.14 Distrib 5.7.26, for Linux (x86_64) using EditLine wrapper Connection id: 15 Current database: mysql ★← Current user: root@localhost SSL: Not in use Current pager: stdout Using outfile: '' Using delimiter: ; Server version: 5.7.26-log MySQL Community Server (GPL) Protocol version: 10 Connection: Localhost via UNIX socket Server characterset: utf8mb4 Db characterset: latin1 Client characterset: utf8mb4 Conn. characterset: utf8mb4 UNIX socket: /var/lib/mysql/mysql.sock Uptime: 1 day 5 hours 50 min 25 sec Threads: 4 Questions: 304 Slow queries: 0 Opens: 242 Flush tables: 1 Open tables: 231 Queries per second avg: 0.002 -------------- mysql> --- ### MySQLレプリケーション間のバージョン制限について date: 2019-07-16 url: https://zatoima.github.io/mysql-replication-version.html tags: MySQL MySQLはレプリケーション間のバージョン制限があり、1バージョンの差異のみ可能。MySQLは論理レプリケーションにも関わらずバージョン制限があることに注意。 MySQL :: MySQL 5.7 Reference Manual :: 16.4.2 Replication Compatibility Between MySQL Versions https://dev.mysql.com/doc/refman/5.7/en/replication-compatibility.html MySQL supports replication from one release series to the next higher release series. For example, you can replicate from a master running MySQL 5.6 to a slave running MySQL 5.7, from a master running MySQL 5.7 to a slave running MySQL 8.0, and so on. (日本語訳) MySQLは、あるリリースシリーズから次のリリースシリーズへのレプリケーションをサポートしています。たとえば、MySQL 5.6を実行しているマスターからMySQL 5.7を実行しているスレーブ、MySQL 5.7を実行しているマスターからMySQL 8.0を実行しているスレーブなどに複製できます。 備考:他DB(Oracle、Postgres)のレプリケーションのバージョン制限 Oracle DataGuard(フィジカル・スタンバイ)は同バージョン、Oracle GoldenGateはバージョン制限無し(≒Certification Matrixに依存) PostgreSQLのストリーミングレプリケーション(物理レプリケーション)は同一バージョンのみ。ロジカルレプリケーション(論理レプリケーション)は他バージョンも可能。 --- ### Oracle Database 19c Standard Edition 2のReal Application Clustersの非サポート date: 2019-07-15 url: https://zatoima.github.io/oracle-19c-se2-desupport.html tags: Oracle Convert SE2 RAC Databases to Single Instance Migrate your SE2 RAC Databases to Enterprise Edition (EE) and purchase the RAC Database Option Migrate your SE2 RAC to the Oracle Cloud 備考:19c SE2でOracle RACを構築しようとした場合 Oracle Universal Installer(OUI)またはOracle Database Upgrade Assistant(DBUA)の使用に関しては、[INS-35465]、及び[DBT-20011]エラーが出力されてしまいます。他バージョンで非サポートの場合でも使い続けることが出来る機能は多かったですが、RACの場合は構成自体が不可の模様です。 [INS-35465] Standard Edition(SE) is not supported for this installation. [DBT-20011] Oracle home xxxxxx is not enabled with RAC option. 参考 My Oracle Suppot Desupport of Oracle Real Application Clusters (RAC) with Oracle Database Standard Edition 19c (Doc ID 2504078.1) Manual Licensing Information https://docs.oracle.com/en/database/oracle/oracle-database/19/dblic/Licensing-Information.html#GUID-0F9EB85D-4610-4EDF-89C2-4916A0E7AC87 Blog Oracle database 19c Standard Edition 2 sem suporte para Real Application Clusters (RAC) ~ DBA Anderson Graf http://www.andersondba.com.br/2019/05/oracle-database-19c-standard-edition-2.html --- ### AWS RDSインスタンスを停止する際の注意事項 date: 2019-07-14 url: https://zatoima.github.io/aws-rds-stop-cautions.html tags: AWS, RDS はじめに RDSの下記マニュアルを見ていていくつかハマるポイントがあるな、と感じたのでメモ。 一時的に Amazon RDS DB インスタンスを停止する - Amazon Relational Database Service https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_StopInstance.html 停止時間の最大日数 最大1週間のみ停止が可能。停止したから永続的に課金されないというわけではないので注意。 DB インスタンスは最大 7 日間停止できます。DB インスタンスを手動で起動しないで 7 日間が経過すると、DB インスタンスは自動的に起動します。 停止可能なDBエンジン 一通りのDBエンジンは停止が出来る。 MariaDB Microsoft SQL Server MySQL Oracle PostgreSQL ただ、マルチ AZ 設定の Amazon RDS for SQL Server DB インスタンスは停止できません。と記載されている通り、マルチAZのSQL Serverの運用は注意。 制約事項 リードレプリカが含まれているか、リードレプリカである DB インスタンスは停止できません。 マルチ AZ 設定の Amazon RDS for SQL Server DB インスタンスは停止できません。 停止された DB インスタンスを変更することはできません。 停止された DB インスタンスに関連付けられているオプショングループを削除することはできません。 停止した DB インスタンスに関連付けられている DB パラメータグループを削除することはできません。 停止された DB インスタンスを変更することはできません。 これは停止してインスタンスタイプをアップグレードしたい、と言った場合、停止中には出来ません、とのこと。 リードレプリカが含まれているか、リードレプリカである DB インスタンスは停止できません。 開発環境ならまだしも本番環境の場合はリードレプリカを使うシステム構成が多いのでこの制約事項のために停止運用が出来ないシステムは多く存在しそう。 まとめ バッファキャッシュ、共有プール(Oracle)やInnoDB バッファプール(MySQL)等は当然DBの再起動が入るとキャッシュから消えてしまう。(MySQLのInnoDB バッファープールのプリロードを使う等すれば良いかもしれない) SQLの性能にはバッファキャッシュや共有プールが非常に重要になってくるので性能や運用管理よりもコストを重視する(開発環境)などの理由が明確にある場合にのみRDSの停止運用をすべき。少なくともDB on EC2の運用とは別の考え方が必要。 参考 RDSを本番環境で停止運用しないほうが良い理由について – サーバーワークスエンジニアブログ http://blog.serverworks.co.jp/tech/2019/06/26/stopdbinstance/ --- ### Oracle Databaseのv_$表とv$表の関係 date: 2019-07-13 url: https://zatoima.github.io/oracle-dynamic-performance-view.html tags: Oracle はじめに **動的パフォーマンス・ビュー(v$表)**は、データベースが稼働している間にデータベース・サーバーが継続して更新している特別なビューです。他DBと比較してもOracleDatabaseの動的パフォーマンス・ビューの多彩さは郡を抜いています。 アクセスする際は v$表 に対してselect文を投げますが、たまに各種ドキュメントを見ると「v_$表」という表記が出てきます。例えば下記はたまたま見つけた例ですが、AWSのDMSのマニュアルにはこのような記載があります。 https://docs.aws.amazon.com/ja_jp/dms/latest/userguide/CHAP_Source.Oracle.html 権限を付与する場合、オブジェクトのシノニムではなく、オブジェクトの実際の名前を使用します。たとえば、V_$OBJECT を下線を含めて使用し、下線のない V$OBJECT は使用しません。 またディクショナリビューを参照する権限を与える場合には、 V_$LICENSE と**アンダーバー**を指定をする必要がありますよね。 SQL> GRANT SELECT ON SYS.V_$LICENSE TO rivus; 権限付与が成功しました。 V_$表とは 下記のマニュアルにもある通り、正確にはv$表は**PUBLIC シノニム**です。V$ARCHIVEの場合、V_$ARCHIVEが 実表 でV$ARCHIVEは シノニム です。権限を付与する際はシノニムではなく実表に対しての権限を付与する必要があるため、上記の通りアンダーバーを付与する必要があるということです。 https://docs.oracle.com/cd/E16338_01/server.112/b56311/dynviews_1001.htm 実際の動的パフォーマンス・ビューは、接頭辞V_$によって識別されます。これらのビューのパブリック・シノニムには、接頭辞V$が付いています。データベース管理者および他のユーザーは、V_$オブジェクトではなく、V$オブジェクトのみにアクセスしてください。 実際の確認した結果は下記の通りです。 SQL> set pages 2000 lin 2000 col OWNER for a10 col SYNONYM_NAME for a15 col TABLE_OWNER for a15 col TABLE_NAME for a15 select OWNER,SYNONYM_NAME,TABLE_OWNER,TABLE_NAME from ALL_SYNONYMS where TABLE_NAME like 'V_$ARCHIVE'; SQL> SQL> SQL> SQL> SQL> SQL> OWNER SYNONYM_NAME TABLE_OWNER TABLE_NAME ---------- --------------- --------------- --------------- PUBLIC V$ARCHIVE SYS V_$ARCHIVE --- ### MySQLでslow_query_log_fileのファイルは事前に作成する必要あり date: 2019-07-03 url: https://zatoima.github.io/mysql-slow_query_log_file-error.html tags: MySQL slow_query_log_file で指定するスロークエリログファイルは事前に作成しておく必要があるという話。常識? スロークエリログ関連のシステム変数 [mysqld] slow_query_log=ON slow_query_log_file = /var/log/slow.log long_query_time=0 事前に作成しておかないとエラーが出力される。 mysqld: File '/var/log/slow.log' not found (Errcode: 13 - Permission denied) 2019-07-01T11:16:23.095556Z 0 [ERROR] Could not use /var/log/slow.log for logging (error 13 - Permission denied). Turning logging off for the server process. To turn it on again: fix the cause, then either restart the query logging by using "SET GLOBAL SLOW_QUERY_LOG=ON" or restart the MySQL server. --- ### AWS EC2上のMySQL環境でレプリケーション構成を構築する date: 2019-07-02 url: https://zatoima.github.io/mysql-aws-ec2-replication.html tags: MySQL, AWS, EC2 はじめに MySQLのレプリケーション環境をAWSのEC2を使って構築します。マスター側、及びスレーブ側どちらもEC2上に作成したMySQLになります。 前提事項 ・MySQLのマスター側、スレーブ側は構築済 ・データの中身は既にマスター側、スレーブ側にて同一 EC2のセキュリティリストの編集 マスターとスレーブで通信をするのでインバウントを編集する必要があります。ここではプライベートIPを限定して許可しています。 スレーブ側のauto.cnfの削除 cd /var/lib/mysql rm -rf auto.cnf systemctl restart mysqld 【実行結果】 [root@awsstg-db002 mysql]# pwd /var/lib/mysql [root@awsstg-db002 mysql]# ls -l auto.cnf -rw-r----- 1 mysql mysql 56 Jun 24 13:25 auto.cnf [root@awsstg-db002 mysql]# [root@awsstg-db002 mysql]# rm -rf auto.cnf [root@awsstg-db002 mysql]# [root@awsstg-db002 mysql]# systemctl restart mysqld マスター側のmy.cnfの編集 下記項目をmy.cnfに追加 #バイナリログの有効化 log-bin #サーバIDの設定 server_id=1 # GTID有効 gtid_mode=on # GTID利用時に必須となる設定(GTIDの一貫性を担保できないSQLの実行を禁止) enforce_gtid_consistency=on スレーブ側のmy.cnfの編集 下記項目をmy.cnfに追加 #バイナリログの有効化 ※スレーブ側として可動する場合は必須ではない log-bin #サーバIDの設定 server_id=2 # GTID有効 gtid_mode=on # GTID利用時に必須となる設定(GTIDの一貫性を担保できないSQLの実行を禁止) enforce_gtid_consistency=on マスター側にてレプリケーションスレーブ用のユーザを作成 grant replication slave on *.* to 'repl'@'10.0.0.11' identified by 'mysql'; select Host, User from mysql.user; 【出力結果】 mysql> grant replication slave on *.* to 'repl'@'10.0.0.11' identified by 'mysql' -> ; Query OK, 0 rows affected, 1 warning (0.01 sec) mysql> select Host, User from mysql.user; +-----------+---------------+ | Host | User | +-----------+---------------+ | 10.0.0.11 | repl | | localhost | mysql.session | | localhost | mysql.sys | | localhost | myuser | | localhost | repl | | localhost | root | +-----------+---------------+ 6 rows in set (0.00 sec) mysql> マスター側にてステータス確認 show master status; 【出力結果】 mysql> show master status\G *************************** 1. row *************************** File: awsstg-db001-bin.000007 Position: 485 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 86a2b2da-9683-11e9-9dd6-067b425ce144:1-42 1 row in set (0.00 sec) mysql> スレーブ側にてレプリケーションスレーブの設定と開始 change master to master_host = '10.0.0.13',master_user = 'repl',master_password = 'mysql',master_log_file = 'awsstg-db001-bin.000007',master_log_pos = 485; #レプリケーションの開始 start slave; show slave status\G 【出力結果】 mysql> change master to master_host = '10.0.0.13',master_user = 'repl',master_password = 'mysql',master_log_file = 'awsstg-db001-bin.000007',master_log_pos = 485; Query OK, 0 rows affected, 2 warnings (0.01 sec) mysql> mysql> show warnings\G *************************** 1. row *************************** Level: Note Code: 1759 Message: Sending passwords in plain text without SSL/TLS is extremely insecure. *************************** 2. row *************************** Level: Note Code: 1760 Message: Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manualfor more information. 2 rows in set (0.00 sec) mysql> mysql> mysql> start slave; Query OK, 0 rows affected (0.00 sec) mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 10.0.0.13 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: awsstg-db001-bin.000007 Read_Master_Log_Pos: 84251854 Relay_Log_File: awsstg-db002-relay-bin.000004 Relay_Log_Pos: 84251325 Relay_Master_Log_File: awsstg-db001-bin.000007 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 84251854 Relay_Log_Space: 84252123 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 1 Master_UUID: 86a2b2da-9683-11e9-9dd6-067b425ce144 Master_Info_File: /var/lib/mysql/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: 86a2b2da-9683-11e9-9dd6-067b425ce144:43-68 Executed_Gtid_Set: 86a2b2da-9683-11e9-9dd6-067b425ce144:1-27:43-68 Auto_Position: 0 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: 1 row in set (0.00 sec) --- ### MySQLのFLUSH PRIVILEGESが必要なケース date: 2019-07-01 url: https://zatoima.github.io/mysql-flush-privileges.html tags: MySQL はじめに MySQLで権限周りのオペレーションをする時に脳死状態で FLUSH PRIVILEGESを実行しているケースがあります。 権限管理の概要 権限周りの情報はuser、db、tables_priv、columns_priv、および procs_priv あたりのテーブルに保持していて、高速化のためにメモリ上のキャッシュに保持している模様。 https://dev.mysql.com/doc/refman/5.6/ja/privileges-provided.html 6.2.1 MySQL で提供される権限 アカウント権限に関する情報は、mysql データベース内の user、db、tables_priv、columns_priv、および procs_priv テーブルに格納されます (セクション6.2.2「権限システム付与テーブル」を参照してください)。MySQL サーバーはこれらのテーブルの内容を起動時にメモリーに読み取り、セクション6.2.6「権限変更が有効化される時期」に示す条件でこれらを再ロードします。 GRANT、REVOKE、SET PASSWORD、RENAME USER で操作を行った場合は特に FLUSH PRIVILEGESは不要と明示的にこちらに書いています。 https://dev.mysql.com/doc/refman/5.6/ja/privilege-changes.html 6.2.6 権限変更が有効化される時期 ユーザーが GRANT、REVOKE、SET PASSWORD、RENAME USER などのアカウント管理ステートメントを使用して、付与テーブルを間接的に変更した場合、サーバーはそれらの変更を認識し、再びすぐに付与テーブルをメモリーにロードします。 INSERT、UPDATE、DELETE などのステートメントを使用して、付与テーブルを直接変更する場合、サーバーを再起動するか、テーブルをリロードするようサーバーに指示するまで、変更内容は権限チェックに影響しません。付与テーブルを直接変更したが、それらをリロードし忘れた場合、サーバーを再起動するまで変更は影響しません。このため、変更したのに違いが現れないことを不思議に思うことがあるかもしれません。 FLUSH PRIVILEGESが不要なケース ユーザ作成 CREATE USER 'mytest'@'localhost' IDENTIFIED BY 'Oracle2019%'; ユーザー一覧を表示する SELECT host, user FROM mysql.user; 権限付与 grant all on *.* to 'mytest'@'localhost' IDENTIFIED BY 'Oracle2019%'; 権限確認 show grants for mytest@localhost; 権限剥奪 revoke all on *.* from 'mytest'@'localhost'; FLUSH PRIVILEGESが必要なケース ユーザ削除 一方、INSERT、UPDATE、DELETE などのステートメントを使用して、付与テーブルを直接変更する場合、サーバーを再起動するか、テーブルをリロードするようサーバーに指示するまで、変更内容は権限チェックに影響しません。と記載があるので、deleteでmysql.userを直接メンテナンスする場合の挙動とDROP USERした場合の挙動を実機で確認してみる。 1.)drop userを使用した場合 DROP USER mytest@'localhost'; drop userの場合はアカウント管理ステートメントになるのでuser関連のメモリ上の情報も同期的にflushされる。(FLUSH PRIVILEGESは不要) 【コマンド結果】 mysql> DROP USER mytest@'localhost'; Query OK, 0 rows affected (0.00 sec) mysql> show grants for mytest@localhost; ERROR 1141 (42000): There is no such grant defined for user 'mytest' on host 'localhost' 2.)mysql.userからdelete文で削除 delete from mysql.user where user like 'mytest' and host like 'localhost'; drop userと異なりこちらのユーザ削除方法の場合は、メモリに権限関連の情報が残ってしまうので FLUSH PRIVILEGES が必要になってくる。 mysql> delete from mysql.user where user like 'mytest' and host like 'localhost'; Query OK, 1 row affected (0.00 sec) mysql> show grants for mytest@localhost; #mytestユーザの情報が残っている。 +--------------------------------------------+ | Grants for mytest@localhost | +--------------------------------------------+ | GRANT USAGE ON *.* TO 'mytest'@'localhost' | +--------------------------------------------+ 1 row in set (0.00 sec) mysql> FLUSH PRIVILEGES; #flush privilegesコマンドで反映 Query OK, 0 rows affected (0.01 sec) mysql> show grants for mytest@localhost; ERROR 1141 (42000): There is no such grant defined for user 'mytest' on host 'localhost' mysql> まとめ 今回はユーザ削除を例に実施してみたが、直接user表をメンテするようなオペレーションする場合はFLUSH PRIVILEGES必要になってくるはず。 --- ### MySQLテーブル内のデータをファイル抽出する date: 2019-06-28 url: https://zatoima.github.io/mysql-file-exporttable.html tags: MySQL ファイル出力方法は大きく分けて2種類ある ①リダイレクトによる出力 echo 'SELECT * FROM t1 ' | mysql -u myuser -p<パスワード> mydb > /tmp/t1.dmp ②SELECT INTO OUTFILE を使用する SELECT * FROM t1 INTO OUTFILE '/var/lib/mysql-files/t1.dmp' FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n'; ファイルの書き込み先はsecure_file_privで許可されたところを指定する。 上記ディレクトリ以外を指定すると下記エラーが発生する。 ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement mysql> SELECT @@secure_file_priv; +-----------------------+ | @@secure_file_priv | +-----------------------+ | /var/lib/mysql-files/ | +-----------------------+ 1 row in set (0.00 sec) 参考 MySQL :: MySQL 5.6 リファレンスマニュアル :: 13.2.9.1 SELECT … INTO 構文 https://dev.mysql.com/doc/refman/5.6/ja/select-into.html SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' FROM test_table; --- ### MySQL検証用テーブル作成(データベース作成~テストデータの準備まで) date: 2019-06-27 url: https://zatoima.github.io/mysql-testtable-create.html tags: MySQL データベース作成、ユーザ作成、権限付与、テーブル作成、テストデータの準備までを実施。 database作成 CREATE DATABASE mydb; show databases; use mydb; ユーザ作成 CREATE USER 'myuser'@'localhost' IDENTIFIED BY 'Oracle2019%'; ユーザー一覧を表示する SELECT host, user FROM mysql.user; 権限付与 grant all on *.* to 'myuser'@'localhost' IDENTIFIED BY 'Oracle2019%'; 作成したユーザで接続 mysql -u myuser -p テーブル作成 CREATE TABLE t1 ( a INT PRIMARY KEY AUTO_INCREMENT, b VARCHAR(10), c VARCHAR(30), d INT UNSIGNED, e DATETIME ); テストデータの挿入 INSERT INTO t1 () VALUES (); INSERT INTO t1 (a) SELECT 0 FROM t1; INSERT INTO t1 (a) SELECT 0 FROM t1; INSERT INTO t1 (a) SELECT 0 FROM t1; INSERT INTO t1 (a) SELECT 0 FROM t1; UPDATE t1 SET b = CONCAT('商品', a), c = SUBSTRING(MD5(RAND()), 1, 30), d = CEIL(RAND() * 10000), e = ADDTIME(CONCAT_WS(' ','2014-01-01' + INTERVAL RAND() * 180 DAY, '00:00:00'), SEC_TO_TIME(FLOOR(0 + (RAND() * 86401)))); 参考 SQLで大量のテストデータ作成 - Qiita https://qiita.com/cobot00/items/8d59e0734314a88d74c7 --- ### EC2インスタンスのホスト名変更 date: 2019-06-24 url: https://zatoima.github.io/aws-ec2-hostname-change.html tags: AWS, EC2 はじめに EC2にログインした時のプロンプト表記が不格好なので明示的に変更したい。REHL7系と少しだけ違うのでメモ。 [ec2-user@ip-10-0-0-9 local]# 設定方法 hostnamectlで変更 sudo hostnamectl set-hostname --static awsstg-db001 /etc/cloud/cloud.cfgを編集する preserve_hostname: trueをcfgファイル内に記述 sudo vi /etc/cloud/cloud.cfg ~中略~ preserve_hostname: true リブートする [ec2-user@awsstg-db001 ~]$ [ec2-user@awsstg-db001 ~]$ hostname awsstg-db001 参考 AMAZON EC2 LINUX の静的ホスト名 RHEL7 CENTOS7 HTTPS://AWS.AMAZON.COM/JP/PREMIUMSUPPORT/KNOWLEDGE-CENTER/LINUX-STATIC-HOSTNAME-RHEL7-CENTOS7/ RHEL、Centos、または Amazon Linux 上のプライベート Amazon EC2 インスタンスに静的ホスト名を割り当てる https://aws.amazon.com/jp/premiumsupport/knowledge-center/linux-static-hostname-rhel-centos-amazon/ --- ### VSCodeのシンタックスハイライトのコピー機能の無効化 date: 2019-06-23 url: https://zatoima.github.io/vscore-syntax-highlighting-disabled.html tags: VSCode, Tools はじめに teratailに数年前に質問して回答ゼロだったシンタックスハイライトのコピー機能の無効化についてようやく方法がわかった。 Visual Studio Code February 2017 | 非公式 - Visual Studio Code Docs https://vscode-doc-jp.github.io/updates/v1_10.html シンタックスハイライトのコピー (Copy with syntax highlighting) 選択されたテキストは、シンタックスハイライトが適用された状態でクリップボードにコピーされるようになりました。 これは、コンテンツを別のアプリケーション (たとえば、Outlook など) に貼り付けるときに非常に便利です。 アプリケーションへ貼り付けられる内容は、正しいフォーマットと色付けを保持しています。 Visual Studio Code - vscodeのシンタックスハイライトのコピー機能の無効化について|teratail https://teratail.com/questions/119990 Visual Studio Codeを使用しています。(Windows版) 下記に示す機能を無効化する方法や手段はありますでしょうか。 https://vscode-doc-jp.github.io/updates/v1_10.html >シンタックスハイライトのコピー (Copy with syntax highlighting) コピーアンドペーストした際に書式情報も一緒にコピーされ困っています。 一度メモ帳に貼り付けたりCtrl+Shift+Vで回避もできますが設定で無効化できるとしたら その方法を知りたいです。 設定方法 「File」-「Preferences」-「Settings」を選択し、その中からEditor: Copy With Syntax Highlightingのチェックを外すこと。 ※VSCodeが古いバージョン(例:1.22)の場合は、上記の方法は実施できなかった。上記が見つからない場合は、まずは最新化を検討した方が良い。今回は1.35.1のバージョンで実施。teratailに質問したときに回答無かったのはシンタックスハイライトを無効化機能が実装されていなかったからかもしれない。 参考 VSCodeでコピーする時に「書式なし」をデフォルトにする - Qiita https://qiita.com/kaityo256/items/d39884c36bd5b35e6427 --- ### VirtualBoxのOracle LinuxにOracle Database 19cをインストール date: 2019-06-22 url: https://zatoima.github.io/oracle-19c-install-single.html tags: Oracle はじめに 前回で必要パッケージやユーザ、ディレクトリの準備が完了したので実際にOracle Database 19cをインストールしてDBを構築していきます。※シングル環境です。OSはOracle Linux 7.6です。 事前準備編 Oracle Database 19cインストール事前準備 | my opinion is my own https://zatoima.github.io/oracle-pre-install-19c.html Oracle Database 19c for Linuxのインストールガイド Oracle Database Databaseインストレーション・ガイド, 19c for Linux https://docs.oracle.com/cd/F19136_01/ladbi/index.html Oracle Database 19cのインストール 事前に「Oracle Software Delivery Cloud」から、「Oracle Database 19.3.0.0.0(V982063-01.zip)」をダウンロードします。 Oracle 18cからruninstallerを使用したORACLE_HOMEへのインストールではなく、unzip形式に変更になっています。 [oracle@dbsrv dbhome_1]$ pwd /u01/app/oracle/product/19.3.0.0/dbhome_1 [oracle@dbsrv dbhome_1]$ ls -l 合計 2987996 -rw-rw-r-- 1 oracle oracle 3059705302 5月 28 11:40 V982063-01.zip [oracle@dbsrv dbhome_1]$ unzip V982063-01.zip Archive: V982063-01.zip creating: drdaas/ creating: drdaas/admin/ inflating: drdaas/admin/drdasqtt_translator_setup.sql inflating: drdaas/admin/drdapkg_db2.sql inflating: drdaas/admin/drdaas.ora inflating: drdaas/admin/drdasqt_set_profile_dd.sql 中略 javavm/admin/classes.bin -> ../../javavm/jdk/jdk8/admin/classes.bin javavm/admin/libjtcjt.so -> ../../javavm/jdk/jdk8/admin/libjtcjt.so jdk/jre/bin/ControlPanel -> jcontrol javavm/admin/lfclasses.bin -> ../../javavm/jdk/jdk8/admin/lfclasses.bin javavm/lib/security/cacerts -> ../../../javavm/jdk/jdk8/lib/security/cacerts javavm/lib/sunjce_provider.jar -> ../../javavm/jdk/jdk8/lib/sunjce_provider.jar javavm/lib/security/README.txt -> ../../../javavm/jdk/jdk8/lib/security/README.txt javavm/lib/security/java.security -> ../../../javavm/jdk/jdk8/lib/security/java.security jdk/jre/lib/amd64/server/libjsig.so -> ../libjsig.so [oracle@dbsrv dbhome_1]$ 不要になったzipファイルを削除します。 [oracle@dbsrv dbhome_1]$ ls -l V982063-01.zip -rw-rw-r-- 1 oracle oracle 3059705302 5月 28 11:40 V982063-01.zip [oracle@dbsrv dbhome_1]$ rm -f V982063-01.zip [oracle@dbsrv dbhome_1]$ DB作成 従来どおり、DBCAを使用してDBを作成します。 DBCA実行中に前バージョンと同様にorainstRoot.shとroot.shの実行を行います。 [root@dbsrv ~]# /u01/app/oraInventory/orainstRoot.sh Changing permissions of /u01/app/oraInventory. Adding read,write permissions for group. Removing read,write,execute permissions for world. Changing groupname of /u01/app/oraInventory to oracle. The execution of the script is complete. [root@dbsrv ~]# /u01/app/oracle/product/19.0.0/dbhome_1/root.sh Performing root user operation. The following environment variables are set as: ORACLE_OWNER= oracle ORACLE_HOME= /u01/app/oracle/product/19.0.0/dbhome_1 Enter the full pathname of the local bin directory: [/usr/local/bin]: Copying dbhome to /usr/local/bin ... Copying oraenv to /usr/local/bin ... Copying coraenv to /usr/local/bin ... Creating /etc/oratab file... Entries will be added to the /etc/oratab file as needed by Database Configuration Assistant when a database is created Finished running generic part of root script. Now product-specific root actions will be performed. Oracle Trace File Analyzer (TFA - Standalone Mode) is available at : /u01/app/oracle/product/19.0.0/dbhome_1/bin/tfactl Note : 1. tfactl will use TFA Service if that service is running and user has been granted access 2. tfactl will configure TFA Standalone Mode only if user has no access to TFA Service or TFA is not installed [root@dbsrv ~]# 環境変数の設定 export TMPDIR=$HOME/tmp export TEMP=$HOME/tmp export ORACLE_BASE=/u01/app/oracle export ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1 export PATH=$ORACLE_HOME/bin:$ORACLE_HOME/jdk/bin:${PATH} export LD_LIBRARY_PATH=$ORACLE_HOME/lib export NLS_LANG=JAPANESE_JAPAN.UTF8 export LANG=ja_JP.UTF-8 プロセス確認 [oracle@dbsrv bin]$ ps -ef | grep db19c1 oracle 31811 1 0 16:43 ? 00:00:00 ora_pmon_db19c1 oracle 31813 1 0 16:43 ? 00:00:00 ora_clmn_db19c1 oracle 31815 1 0 16:43 ? 00:00:00 ora_psp0_db19c1 oracle 31818 1 1 16:43 ? 00:00:03 ora_vktm_db19c1 oracle 31822 1 0 16:43 ? 00:00:00 ora_gen0_db19c1 oracle 31824 1 0 16:43 ? 00:00:00 ora_mman_db19c1 oracle 31828 1 0 16:43 ? 00:00:00 ora_gen1_db19c1 oracle 31831 1 0 16:43 ? 00:00:00 ora_diag_db19c1 oracle 31833 1 0 16:43 ? 00:00:00 ora_ofsd_db19c1 oracle 31836 1 0 16:43 ? 00:00:00 ora_dbrm_db19c1 oracle 31838 1 0 16:43 ? 00:00:00 ora_vkrm_db19c1 oracle 31840 1 0 16:43 ? 00:00:00 ora_svcb_db19c1 oracle 31842 1 0 16:43 ? 00:00:00 ora_pman_db19c1 oracle 31844 1 0 16:43 ? 00:00:00 ora_dia0_db19c1 oracle 31846 1 0 16:43 ? 00:00:00 ora_dbw0_db19c1 oracle 31848 1 0 16:43 ? 00:00:00 ora_lgwr_db19c1 oracle 31850 1 0 16:43 ? 00:00:00 ora_lg00_db19c1 oracle 31852 1 0 16:43 ? 00:00:00 ora_ckpt_db19c1 oracle 31854 1 0 16:43 ? 00:00:00 ora_lg01_db19c1 oracle 31856 1 0 16:43 ? 00:00:00 ora_smon_db19c1 oracle 31858 1 0 16:43 ? 00:00:00 ora_smco_db19c1 oracle 31860 1 0 16:43 ? 00:00:00 ora_w000_db19c1 oracle 31862 1 0 16:43 ? 00:00:00 ora_reco_db19c1 oracle 31864 1 0 16:43 ? 00:00:00 ora_w001_db19c1 oracle 31866 1 0 16:43 ? 00:00:00 ora_lreg_db19c1 oracle 31868 1 0 16:43 ? 00:00:00 ora_pxmn_db19c1 oracle 31872 1 1 16:43 ? 00:00:02 ora_mmon_db19c1 oracle 31874 1 0 16:43 ? 00:00:00 ora_mmnl_db19c1 oracle 31876 1 0 16:43 ? 00:00:00 ora_d000_db19c1 oracle 31878 1 0 16:43 ? 00:00:00 ora_s000_db19c1 oracle 31880 1 0 16:43 ? 00:00:00 ora_tmon_db19c1 oracle 31885 1 0 16:44 ? 00:00:00 ora_m000_db19c1 oracle 31887 1 0 16:44 ? 00:00:00 ora_m001_db19c1 oracle 31894 1 0 16:44 ? 00:00:00 ora_tt00_db19c1 oracle 31896 1 0 16:44 ? 00:00:00 ora_arc0_db19c1 oracle 31898 1 0 16:44 ? 00:00:00 ora_tt01_db19c1 oracle 31900 1 0 16:44 ? 00:00:00 ora_arc1_db19c1 oracle 31902 1 0 16:44 ? 00:00:00 ora_arc2_db19c1 oracle 31904 1 0 16:44 ? 00:00:00 ora_arc3_db19c1 oracle 31906 1 0 16:44 ? 00:00:00 ora_tt02_db19c1 oracle 31911 1 0 16:44 ? 00:00:00 ora_aqpc_db19c1 oracle 31913 1 0 16:44 ? 00:00:00 ora_w002_db19c1 oracle 31917 1 0 16:44 ? 00:00:00 ora_p000_db19c1 oracle 31919 1 0 16:44 ? 00:00:00 ora_p001_db19c1 oracle 31921 1 0 16:44 ? 00:00:00 ora_p002_db19c1 oracle 31923 1 0 16:44 ? 00:00:00 ora_p003_db19c1 oracle 31926 1 0 16:44 ? 00:00:01 ora_cjq0_db19c1 oracle 32039 1 0 16:44 ? 00:00:00 ora_w003_db19c1 oracle 32098 1 0 16:44 ? 00:00:00 ora_w004_db19c1 oracle 32101 1 0 16:44 ? 00:00:00 ora_qm02_db19c1 oracle 32105 1 0 16:44 ? 00:00:00 ora_q002_db19c1 oracle 32107 1 0 16:44 ? 00:00:00 ora_q003_db19c1 oracle 32121 1 0 16:44 ? 00:00:00 ora_m002_db19c1 oracle 32123 1 2 16:44 ? 00:00:05 ora_m003_db19c1 oracle 32149 1 0 16:44 ? 00:00:00 ora_m004_db19c1 oracle 32151 1 0 16:44 ? 00:00:00 ora_q004_db19c1 oracle 32157 1 0 16:44 ? 00:00:00 ora_q005_db19c1 oracle 32217 1 0 16:44 ? 00:00:00 ora_w005_db19c1 --- ### DBCA実行時の[DBT-06103] The port (1,521) is already in use.について date: 2019-06-20 url: https://zatoima.github.io/oracle-oraerror-DBT06103.html tags: Oracle はじめに DBCAでDB作成する際にリスナーを新規で作成するケースは多くあると思いますが、 下記エラーで次の画面に進めないことがあります。 [DBT-06103] The port (1,521) is already in use. 原因 「/etc/hosts」に自ホストの情報が記載されていないことが原因でした。 下記のように記載することでこのエラーは出力しないようになりました。 [root@dbsrv ~]# vi /etc/hosts [root@dbsrv ~]# [root@dbsrv ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.56.231 dbsrv.oracle.jp dbsrv 参考 [DBT-06103] The port (5,500) is already in use. ACTION: Specify a free port (ドキュメントID 2277154.1) --- ### Oracle Database 19cインストール事前準備 date: 2019-06-14 url: https://zatoima.github.io/oracle-pre-install-19c.html tags: Oracle はじめに 前回の記事でインストールの前提条件であるOracle Linux7.6をインストールしたので、今回は続きをやっていきます。DBインストール、DB構築の事前準備です。 Oracle Database 19c for Linuxのインストールガイドはこちらです。 Oracle Database Databaseインストレーション・ガイド, 19c for Linux https://docs.oracle.com/cd/F19136_01/ladbi/index.html ホスト名の変更 #ホスト名の変更 hostnamectl set-hostname dbsrv.oracle.jp ※セッションを抜けて再度ログインする [root@localhost ~]# hostnamectl set-hostname dbsrv.oracle.jp [root@localhost ~]# [root@localhost ~]# echo $? 0 [root@localhost ~]# ファイアーウォールの停止 #ファイアーウォールを停止 systemctl status firewalld systemctl stop firewalld systemctl status firewalld #ファイアーウォール停止を恒久化 systemctl disable firewalld systemctl status firewalld [root@localhost ~]# [root@localhost ~]# systemctl status firewalld ● firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled) Active: active (running) since 木 2019-06-13 16:41:42 JST; 7min ago Docs: man:firewalld(1) Main PID: 3423 (firewalld) Tasks: 2 CGroup: /system.slice/firewalld.service └─3423 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid 6月 13 16:41:40 localhost.localdomain systemd[1]: Starting firewalld - dynamic firewall daemon... 6月 13 16:41:42 localhost.localdomain systemd[1]: Started firewalld - dynamic firewall daemon. [root@localhost ~]# [root@localhost ~]# systemctl stop firewalld [root@localhost ~]# echo $? 0 [root@localhost ~]# [root@localhost ~]# [root@localhost ~]# [root@localhost ~]# systemctl status firewalld ● firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled) Active: inactive (dead) since 木 2019-06-13 16:49:06 JST; 4s ago Docs: man:firewalld(1) Process: 3423 ExecStart=/usr/sbin/firewalld --nofork --nopid $FIREWALLD_ARGS (code=exited, status=0/SUCCESS) Main PID: 3423 (code=exited, status=0/SUCCESS) 6月 13 16:41:40 localhost.localdomain systemd[1]: Starting firewalld - dynamic firewall daemon... 6月 13 16:41:42 localhost.localdomain systemd[1]: Started firewalld - dynamic firewall daemon. 6月 13 16:49:05 dbsrv.oracle.jp systemd[1]: Stopping firewalld - dynamic firewall daemon... 6月 13 16:49:06 dbsrv.oracle.jp systemd[1]: Stopped firewalld - dynamic firewall daemon. [root@localhost ~]# [root@localhost ~]# [root@localhost ~]# [root@localhost ~]# [root@localhost ~]# systemctl disable firewalld Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service. Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service. [root@localhost ~]# [root@localhost ~]# echo $? 0 [root@localhost ~]# [root@localhost ~]# [root@localhost ~]# [root@localhost ~]# systemctl status firewalld ● firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled) Active: inactive (dead) Docs: man:firewalld(1) 6月 13 16:41:40 localhost.localdomain systemd[1]: Starting firewalld - dynamic firewall daemon... 6月 13 16:41:42 localhost.localdomain systemd[1]: Started firewalld - dynamic firewall daemon. 6月 13 16:49:05 dbsrv.oracle.jp systemd[1]: Stopping firewalld - dynamic firewall daemon... 6月 13 16:49:06 dbsrv.oracle.jp systemd[1]: Stopped firewalld - dynamic firewall daemon. [root@localhost ~]# SELinuxの無効化 -- SELinuxの無効化 vi /etc/selinux/config cat /etc/selinux/config [root@localhost ~]# cat /etc/selinux/config # This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. #SELINUX=enforcing SELINUX=disabled ★←disabledに変更 # SELINUXTYPE= can take one of three values: # targeted - Targeted processes are protected, # minimum - Modification of targeted policy. Only selected processes are protected. # mls - Multi Level Security protection. SELINUXTYPE=targeted 「oracle-database-preinstall-19c」パッケージの実行 yumでパッケージをインストールします。 yum install -y oracle-database-preinstall-19c [oracle@dbsrv ~]$ su - パスワード: 最終ログイン: 2019/06/13 (木) 17:10:03 JST日時 pts/0 [root@dbsrv ~]# yum install -y oracle-database-preinstall-19c 読み込んだプラグイン:langpacks, ulninfo ol7_UEKR5 | 2.5 kB 00:00:00 ol7_latest | 2.7 kB 00:00:00 (1/5): ol7_UEKR5/x86_64/updateinfo | 27 kB 00:00:00 (2/5): ol7_latest/x86_64/group | 810 kB 00:00:00 (3/5): ol7_UEKR5/x86_64/primary_db | 3.9 MB 00:00:00 (4/5): ol7_latest/x86_64/updateinfo | 938 kB 00:00:01 (5/5): ol7_latest/x86_64/primary_db | 24 MB 00:00:01 依存性の解決をしています --> トランザクションの確認を実行しています。 ---> パッケージ oracle-database-preinstall-19c.x86_64 0:1.0-1.el7 を インストール --> 依存性の処理をしています: ksh のパッケージ: oracle-database-preinstall-19c-1.0-1.el7.x86_64 --> 依存性の処理をしています: libaio-devel のパッケージ: oracle-database-preinstall-19c-1.0-1.el7.x86_64 --> トランザクションの確認を実行しています。 ---> パッケージ ksh.x86_64 0:20120801-139.0.1.el7 を インストール ---> パッケージ libaio-devel.x86_64 0:0.3.109-13.el7 を インストール --> 依存性解決を終了しました。 依存性を解決しました ============================================================================================================================================================================================ Package アーキテクチャー バージョン リポジトリー 容量 ============================================================================================================================================================================================ インストール中: oracle-database-preinstall-19c x86_64 1.0-1.el7 ol7_latest 18 k 依存性関連でのインストールをします: ksh x86_64 20120801-139.0.1.el7 ol7_latest 883 k libaio-devel x86_64 0.3.109-13.el7 ol7_latest 12 k トランザクションの要約 ============================================================================================================================================================================================ インストール 1 パッケージ (+2 個の依存関係のパッケージ) 総ダウンロード容量: 913 k インストール容量: 3.2 M Downloading packages: 警告: /var/cache/yum/x86_64/7Server/ol7_latest/packages/libaio-devel-0.3.109-13.el7.x86_64.rpm: ヘッダー V3 RSA/SHA256 Signature、鍵 ID ec551f03: NOKEY ] 0.0 B/s | 0 B --:--:-- ETA libaio-devel-0.3.109-13.el7.x86_64.rpm の公開鍵がインストールされていません (1/3): libaio-devel-0.3.109-13.el7.x86_64.rpm | 12 kB 00:00:00 (2/3): ksh-20120801-139.0.1.el7.x86_64.rpm | 883 kB 00:00:00 (3/3): oracle-database-preinstall-19c-1.0-1.el7.x86_64.rpm | 18 kB 00:00:00 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 合計 2.0 MB/s | 913 kB 00:00:00 file:///etc/pki/rpm-gpg/RPM-GPG-KEY-oracle から鍵を取得中です。 Importing GPG key 0xEC551F03: Userid : "Oracle OSS group (Open Source Software group) <build@oss.oracle.com>" Fingerprint: 4214 4123 fecf c55b 9086 313d 72f9 7b74 ec55 1f03 Package : 7:oraclelinux-release-7.6-1.0.15.el7.x86_64 (@anaconda/7.6) From : /etc/pki/rpm-gpg/RPM-GPG-KEY-oracle Running transaction check Running transaction test Transaction test succeeded Running transaction インストール中 : ksh-20120801-139.0.1.el7.x86_64 1/3 インストール中 : libaio-devel-0.3.109-13.el7.x86_64 2/3 インストール中 : oracle-database-preinstall-19c-1.0-1.el7.x86_64 3/3 検証中 : libaio-devel-0.3.109-13.el7.x86_64 1/3 検証中 : ksh-20120801-139.0.1.el7.x86_64 2/3 検証中 : oracle-database-preinstall-19c-1.0-1.el7.x86_64 3/3 インストール: oracle-database-preinstall-19c.x86_64 0:1.0-1.el7 依存性関連をインストールしました: ksh.x86_64 0:20120801-139.0.1.el7 libaio-devel.x86_64 0:0.3.109-13.el7 完了しました! [root@dbsrv ~]# 「/etc/sysctl.conf」が変更されているはずです。 [root@dbsrv ~]# cat /etc/sysctl.conf # sysctl settings are defined through files in # /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/. # # Vendors settings live in /usr/lib/sysctl.d/. # To override a whole file, create a new file with the same in # /etc/sysctl.d/ and put new settings there. To override # only specific settings, add a file with a lexically later # name in /etc/sysctl.d/ and put new settings there. # # For more information, see sysctl.conf(5) and sysctl.d(5). # oracle-database-preinstall-19c setting for fs.file-max is 6815744 fs.file-max = 6815744 # oracle-database-preinstall-19c setting for kernel.sem is '250 32000 100 128' kernel.sem = 250 32000 100 128 # oracle-database-preinstall-19c setting for kernel.shmmni is 4096 kernel.shmmni = 4096 # oracle-database-preinstall-19c setting for kernel.shmall is 1073741824 on x86_64 kernel.shmall = 1073741824 # oracle-database-preinstall-19c setting for kernel.shmmax is 4398046511104 on x86_64 kernel.shmmax = 4398046511104 # oracle-database-preinstall-19c setting for kernel.panic_on_oops is 1 per Orabug 19212317 kernel.panic_on_oops = 1 # oracle-database-preinstall-19c setting for net.core.rmem_default is 262144 net.core.rmem_default = 262144 # oracle-database-preinstall-19c setting for net.core.rmem_max is 4194304 net.core.rmem_max = 4194304 # oracle-database-preinstall-19c setting for net.core.wmem_default is 262144 net.core.wmem_default = 262144 # oracle-database-preinstall-19c setting for net.core.wmem_max is 1048576 net.core.wmem_max = 1048576 # oracle-database-preinstall-19c setting for net.ipv4.conf.all.rp_filter is 2 net.ipv4.conf.all.rp_filter = 2 # oracle-database-preinstall-19c setting for net.ipv4.conf.default.rp_filter is 2 net.ipv4.conf.default.rp_filter = 2 # oracle-database-preinstall-19c setting for fs.aio-max-nr is 1048576 fs.aio-max-nr = 1048576 # oracle-database-preinstall-19c setting for net.ipv4.ip_local_port_range is 9000 65500 net.ipv4.ip_local_port_range = 9000 65500 ユーザ・グループの追加 今回はRAC環境ではなくシングル環境なのでRAC環境用のユーザはコメントアウトしています。 groupadd -g 54321 oinstall groupadd -g 54322 dba groupadd -g 54323 oper #groupadd -g 54324 backupdba #groupadd -g 54325 dgdba #groupadd -g 54326 kmdba #groupadd -g 54327 asmdba #groupadd -g 54328 asmoper #groupadd -g 54329 asmadmin #groupadd -g 54330 racdba useradd -u 54321 -g oinstall -G dba,oper oracle cat /etc/passwd [root@dbsrv ~]# cat /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin ~中略~ tcpdump:x:72:72::/:/sbin/nologin oracle:x:1000:1000:oracle:/home/oracle:/bin/bash vboxadd:x:988:1::/var/run/vboxadd:/bin/false [root@dbsrv ~]# ディレクトリ作成 #mkdir -p /u01/app/grid mkdir -p /u01/app/oracle mkdir -p /u01/app/oraInventory #mkdir -p /u01/app/19.3.0.0/grid mkdir -p /u01/app/oracle/product/19.3.0.0/dbhome_1 #chown -R grid:oinstall /u01 chown -R oracle:oinstall /u01/app/oracle chmod -R 775 /u01 /etc/hostsの変更 [root@dbsrv ~]# vi /etc/hosts [root@dbsrv ~]# [root@dbsrv ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.56.231 dbsrv.oracle.jp dbsrv [root@dbsrv ~]# 次回 次回はOracle Database 19cのインストールを行う予定です。 Oracle Database 19cのインストールは下記にまとめました。 Oracle Database 19cインストール | my opinion is my own https://zatoima.github.io/oracle-19c-install-single.html --- ### MySQLのサポートプラットフォームとサポート期間 date: 2019-06-13 url: https://zatoima.github.io/mysql-support-platform-period.html tags: MySQL MySQLのサポートプラットフォーム MySQL :: Supported Platforms: MySQL Database https://www.mysql.com/support/supportedplatforms/database.html サポートポリシー Lifetime Support Policy | Oracle Support | Oracle 日本 https://www.oracle.com/jp/support/lifetime-support/ サポート期間 「Oracle’s MySQL Releases」で検索 Oracle Lifetime Support Policy for Technology Products Guide https://www.oracle.com/us/assets/lifetime-support-technology-069183.pdf --- ### Linuxのバージョンとカーネルバージョン(UEK、REHL) date: 2019-06-11 url: https://zatoima.github.io/linux-uek-rehl-version.html tags: Linux 使用しているOSがRHELだけならば1つ目のRed HatのPORTALページだけで良いが、たまにOracle LinuxのUEKを使う関係上、2つ目のURLも大事。 Red Hat Enterprise Linuxのバージョンとカーネルバージョン Red Hat Enterprise Linux のリリース日と収録カーネルの一覧 - RED HAT CUSTOMER PORTAL HTTPS://ACCESS.REDHAT.COM/JA/ARTICLES/16476 リリース 製品リリース日 Red Hat がリリースするエラータ日* カーネルのバージョン RHEL 8 2019-05-07 - 4.18.0-80 リリース 製品リリース日 Red Hat がリリースするエラータ日* カーネルのバージョン RHEL 7.6 2018-10-30 2018-10-30 RHBA-2018:3014 3.10.0-957 RHEL 7.5 2018-04-10 2018-04-10 RHEA-2018:0700 3.10.0-862 RHEL 7.4 2017-07-31 2017-07-31 RHBA-2017:1850 3.10.0-693 RHEL 7.3 2016-11-03 2016-11-03 RHEA-2016-2544 3.10.0-514 RHEL 7.2 2015-11-19 2015-11-19 RHEA-2015:2461 3.10.0-327 RHEL 7.1 2015-03-05 2015-03-05 RHEA-2015:0524 3.10.0-229 RHEL 7.0 GA 2014-06-09 - 3.10.0-123 RHEL 7.0 Beta 2013-12-11 - 3.10.0-54.0.1 リリース 製品リリース日 Red Hat がリリースするエラータ日* カーネルのバージョン RHEL 6.10 2018-06-19 2018-06-19 RHBA-2018:1856 2.6.32-754 RHEL 6.9 2017-03-21 2017-03-21 RHSA-2017:0817 2.6.32-696 RHEL 6.8 2016-05-10 2016-05-10 RHSA-2016:0855-1 2.6.32-642 RHEL 6.7 2015-07-22 2015-07-22 RHEA-2015:1423 2.6.32-573 RHEL 6.6 2014-10-14 2014-10-13 RHEA-2014:1608 2.6.32-504 RHEL 6.5 2013-11-21 2013-11-20 RHSA-2013:1645-2 2.6.32-431 RHEL 6.4 2013-02-21 2013-02-21 RHSA-2013-0496 2.6.32-358 RHEL 6.3 2012-06-20 2012-06-19 RHSA-2012-0862 2.6.32-279 RHEL 6.2 2011-12-06 2011-12-06 RHEA-2011:1743 2.6.32-220 RHEL 6.1 2011-05-19 2011-05-19 RHEA-2011:0540 2.6.32-131.0.15 RHEL 6.0 2010-11-09 - 2.6.32-71 リリース 製品リリース日 Red Hat がリリースするエラータ日* カーネルのバージョン RHEL 5.11 2014-09-16 2014-09-16 RHEA-2014-1238 2.6.18-398 RHEL 5.10 2013-10-01 2013-09-30 RHEA-2013-1311 2.6.18-371 RHEL 5.9 2013-01-07 2013-01-07 RHEA-2013-0021 2.6.18-348 RHEL 5.8 2012-02-20 2012-02-20 RHEA-2012:0315 2.6.18-308 RHEL 5.7 2011-07-21 2011-07-20 RHEA-2011:0977 2.6.18-274 RHEL 5.6 2011-01-13 2011-01-12 RHEA-2011:0020 2.6.18-238 RHEL 5.5 2010-03-30 2010-03-30 RHEA-2010:0207 2.6.18-194 RHEL 5.4 2009-09-02 2009-09-02 RHEA-2009:1400 2.6.18-164 RHEL 5.3 2009-01-20 2009-01-20 RHEA-2009:0133 2.6.18-128 RHEL 5.2 2008-05-21 2008-05-20 RHEA-2008:0436 2.6.18-92 RHEL 5.1 2007-11-07 2007-11-07 RHEA-2007:0854 2.6.18-53 RHEL 5.0 2007-03-15 - 2.6.18-8 リリース/アップデート 製品リリース日 Red Hat がリリースするエラータ日* カーネルのバージョン RHEL 4 Update 9 2011-02-16 2011-02-16 RHEA-2011:0251 2.6.9-100 RHEL 4 Update 8 2009-05-19 2009-05-18 RHEA-2009:1002 2.6.9-89 RHEL 4 Update 7 2008-07-29 2008-07-24 RHEA-2008:0769 2.6.9-78 RHEL 4 Update 6 2007-11-15 2007-11-15 RHBA-2007:0897 2.6.9-67 RHEL 4 Update 5 2007-05-01 2007-04-27 RHBA-2007:0196 2.6.9-55 RHEL 4 Update 4 2006-08-10 2006-08-10 RHBA-2006:0601 2.6.9-42 RHEL 4 Update 3 2006-03-12 2006-03-07 RHBA-2006:0149 2.6.9-34 RHEL 4 Update 2 2005-10-05 2005-10-05 RHEA-2005:786 2.6.9-22 RHEL 4 Update 1 2005-06-08 2005-06-08 RHEA-2005:318 2.6.9-11 RHEL 4 GA 2005-02-15 - 2.6.9-5 Oracle Linux(UEK)のバージョンとカーネルバージョン Oracle Linux and Unbreakable Enterprise Kernel (UEK) Releases | Oracle Simon Coter Blog https://blogs.oracle.com/scoter/oracle-linux-and-unbreakable-enterprise-kernel-uek-releases OL Release Initial UEK kernel Initial RHCK kernel UEK2 supported UEK3 supported UEK4 supported UEK5 supported OL6U0 kernel-uek-2.6.32-100.28.5 kernel-2.6.32-71 No. OL6U2 required No. OL6U5 required No. OL6U8 required Not Available OL6U1 kernel-uek-2.6.32-100.34.1 kernel-2.6.32-131.0.15 No. OL6U2 required No. OL6U5 required No. OL6U8 required Not Available OL6U2 kernel-uek-2.6.32-300.3.1 kernel-2.6.32-220 Yes No. OL6U5 required No. OL6U8 required Not Available OL6U3 kernel-uek-2.6.39-200.24.1 kernel-2.6.32-279 Yes, default No. OL6U5 required No. OL6U8 required Not Available OL6U4 kernel-uek-2.6.39-400.17.1 kernel-2.6.32-358 Yes, default No. OL6U5 required No. OL6U8 required Not Available OL6U5 kernel-uek-3.8.13-16.2.1 kernel-2.6.32-431 Yes Yes, default No. OL6U8 required Not Available OL6U6 kernel-uek-3.8.13-44.1.1 kernel-2.6.32-504 Yes Yes, default No. OL6U8 required Not Available OL6U7 kernel-uek-3.8.13-68.3.4 kernel-2.6.32-573 Yes Yes, default No. OL6U8 required Not Available OL6U8 kernel-uek-4.1.12-37.4.1 kernel-2.6.32-642 Yes Yes Yes, default Not Available OL6U9 kernel-uek-4.1.12-61.1.28 kernel-2.6.32-696 Yes Yes Yes, default Not Available OL6U10 kernel-uek-4.1.12-124.16.4 kernel-2.6.32-754 Yes Yes Yes, default Not Available OL7U0 kernel-uek-3.8.13-35.3.1 kernel-3.10.0-123 Not Available Yes, default No. OL7U3 required No. OL7U5 required OL7U1 kernel-uek-3.8.13-55.1.6 kernel-3.10.0-229 Not Available Yes, default No. OL7U3 required No. OL7U5 required OL7U2 kernel-uek-3.8.13-98.7.1 kernel-3.10.0-327 Not Available Yes, default No. OL7U3 required No. OL7U5 required OL7U3 kernel-uek-4.1.12-61.1.18 kernel-3.10.0-514 Not Available Yes Yes, default No. OL7U5 required OL7U4 kernel-uek-4.1.12-94.3.9 kernel-3.10.0-693 Not Available Yes Yes, default No. OL7U5 required OL7U5 kernel-uek-4.1.12-112.16.4 kernel-3.10.0-862 Not Available Yes Yes, default Yes OL7U6 kernel-uek-4.14.35-1818.3.3 kernel-3.10.0-957 Not Available Yes Yes Yes, default --- ### Oracle Databaseのsystem表領域の領域縮小 date: 2019-05-02 url: https://zatoima.github.io/oracle-system-tablespace-shrink.html tags: Oracle はじめに ユーザ表領域ではなく、system表領域、sysaux表領域を拡張した後にshrinkやデータファイルのdropができるのかを確認 system表領域は制限が多くDBの稼働に必須なためどのように動作するのかを改めて調査 データファイルと容量確認 SELECT tablespace_name, file_name, status, bytes/1024/1024 mbytes, increment_by, autoextensible, online_status FROM dba_data_files WHERE tablespace_name = 'SYSTEM'; SQL実行結果 SQL> SELECT 2 tablespace_name, 3 file_name, 4 status, 5 bytes/1024/1024 mbytes, 6 increment_by, 7 autoextensible, 8 online_status 9 FROM 10 dba_data_files 11 WHERE 12 tablespace_name = 'SYSTEM'; TABLESPACE_NAME FILE_NAME STATUS MBYTES INCREMENT_BY AUTOEXTENSIBLE ONLINE_STATUS SYSTEM /u01/app/oracle/oradata/DB112S/datafile/o1_mf_system_g97nco87_.dbf AVAILABLE 770 1280 YES SYSTEM 表領域の容量確認 SELECT t.tablespace_name name , t.status , t.contents type , t.extent_management extmgt , t.allocation_type alloc , t.initial_extent/1024 init_kb , t.segment_space_management segmgt , TO_CHAR(NVL(d.bytes - NVL(f.bytes, 0), 0)/1024/1024, '9,999,990.9') "USED(MB)" , TO_CHAR(NVL(d.bytes, 0)/1024/1024, '9,999,990.9') "TOTAL(MB)" , TO_CHAR(NVL(d.bytes - NVL(f.bytes, 0), 0)/(NVL(d.bytes, -1)/100), '990.0') "USED(%)" FROM dba_tablespaces t , (SELECT tablespace_name, SUM(bytes) bytes FROM dba_data_files GROUP BY tablespace_name) d , (SELECT tablespace_name, SUM(bytes) bytes FROM dba_free_space GROUP BY tablespace_name) f WHERE t.tablespace_name = d.tablespace_name(+) AND t.tablespace_name = f.tablespace_name(+) AND NOT (t.extent_management = 'LOCAL' AND t.contents = 'TEMPORARY') UNION ALL SELECT t.tablespace_name name , t.status , t.contents type , t.extent_management extmgt , t.allocation_type alloc , t.initial_extent/1024 init_kb , t.segment_space_management segmgt , TO_CHAR(NVL(f.bytes, 0)/1024/1024, '9,999,990.9') "USED(MB)" , TO_CHAR(NVL(d.bytes, 0)/1024/1024, '9,999,990.9') "TOTAL(MB)" , TO_CHAR(NVL(f.bytes/(d.bytes/100), 0), '990.0') "USED(%)" FROM dba_tablespaces t , (SELECT tablespace_name, SUM(bytes) bytes FROM dba_temp_files GROUP BY tablespace_name) d , (SELECT tablespace_name, SUM(bytes_cached) bytes FROM v$temp_extent_pool GROUP BY tablespace_name) f WHERE t.tablespace_name = d.tablespace_name(+) AND t.tablespace_name = f.tablespace_name(+) AND t.extent_management = 'LOCAL' AND t.contents = 'TEMPORARY' ORDER BY name ; SQL実行結果 NAME STATUS TYPE EXTMGT ALLOC INIT_KB SEGMGT USED(MB) TOTAL(MB) USED(%) GGDATA ONLINE PERMANENT LOCAL SYSTEM 64 AUTO 2.8 5,120.0 0.1 SYSAUX ONLINE PERMANENT LOCAL SYSTEM 64 AUTO 534.1 570.0 93.7 SYSTEM ONLINE PERMANENT LOCAL SYSTEM 64 MANUAL 752.4 770.0 97.7 TEMP ONLINE TEMPORARY LOCAL UNIFORM 1024 MANUAL 28.0 29.0 96.6 UNDOTBS1 ONLINE UNDO LOCAL SYSTEM 64 MANUAL 32.6 70.0 46.5 USERS ONLINE PERMANENT LOCAL SYSTEM 64 AUTO 1.3 5.0 26.3 表領域拡張(データファイルの追加) alter tablespace SYSTEM add datafile '/u01/app/oracle/oradata/DB112S/datafile/system01.dbf' size 1G autoextend on next 100M; 表領域の縮小系のオペレーション 表領域縮小(データファイルの削除) 上記で新規に追加したデータファイルを削除するときにはエラーになる。 ALTER TABLESPACE SYSTEM DROP DATAFILE '/u01/app/oracle/oradata/DB112S/datafile/system01.dbf'; SQL実行結果 SQL> ALTER TABLESPACE SYSTEM DROP DATAFILE '/u01/app/oracle/oradata/DB112S/datafile/system01.dbf'; 次のコマンドの開始中にエラーが発生しました : 行 1 - ALTER TABLESPACE SYSTEM DROP DATAFILE '/u01/app/oracle/oradata/DB112S/datafile/system01.dbf' エラー・レポート - ORA-01541: SYSTEM表領域はオフラインにできません。必要な場合はシャットダウンしてください 01541. 00000 - "system tablespace cannot be brought offline; shut down if necessary" *Cause: Tried to bring system tablespace offline *Action: Shutdown if necessary to do recovery SQL> 表領域縮小(リサイズ) 既存のデータファイルのサイズをresizeします。 ALTER DATABASE DATAFILE '/u01/app/oracle/oradata/DB112S/datafile/o1_mf_system_g97nco87_.dbf' RESIZE 800M; SQL実行結果 SQL> ALTER DATABASE DATAFILE '/u01/app/oracle/oradata/DB112S/datafile/o1_mf_system_g97nco87_.dbf' RESIZE 800M; Databaseが変更されました。 表領域縮小(リサイズ) system表領域を構成するデータファイルがスモール・ファイル表領域なのでエラーになる。 alter tablespace SYSTEM resize 800M ; SQL実行結果 SQL> alter tablespace SYSTEM resize 800M ; 次のコマンドの開始中にエラーが発生しました : 行 1 - alter tablespace SYSTEM resize 800M エラー・レポート - ORA-32773: SMALLFILE表領域SYSTEMに対する操作はサポートされていません 32773. 00000 - "operation not supported for smallfile tablespace %s" *Cause: An attempt was made to perform an operation which is supported only for bigfile tablespaces, e.g. resize tablespace. *Action: Use the appropriate clause of the ALTER DATABASE DATAFILE command instead. SQL> --- ### Visual Studio Code(VSCode)の設定移行 date: 2019-04-30 url: https://zatoima.github.io/vscode-setting-iko.html tags: VSCode, Tools 社用のPCが調子悪くWindows10のクリーンインストールを行いました。各種ツールの設定を引き継ぐことが出来ずに絶望しています。 毎回調べるVSCodeの設定を引き継ぐ方法を記載します。 Dropbox等を使用した環境設定ファイルの共有方法や拡張機能の「Setting Sync」を使用した共有方法が別途ありますが、今回はファイルのコピーだけで実施可能な方法になります。 Visual Studio Code の設定を共有・バックアップする - Qiita https://qiita.com/maromaro3721/items/b6d71a5e5d2d6433778a VSCode(Visual Studio Code)の設定を同期させる拡張機能「Setting Sync」が便利 | カレリエ https://www.karelie.net/vscode-setting-sync/ 拡張機能 下記フォルダに格納されている全サブフォルダを新環境側にコピーして終わりです。 C:\Users\ユーザー名\.vscode\extensions 2019/04/06 15:47 <DIR> . 2019/04/06 15:47 <DIR> .. 2019/04/06 15:47 <DIR> davidhouchin.whitespace-plus-0.0.5 2019/04/06 15:47 <DIR> ms-mssql.mssql-1.5.0 2019/04/06 15:47 <DIR> ms-vscode.sublime-keybindings-4.0.0 2019/04/06 15:47 <DIR> sandcastle.whitespace-0.0.5 2019/04/06 15:47 <DIR> sensourceinc.vscode-sql-beautify-0.0.4 2019/04/06 15:47 <DIR> shakram02.bash-beautify-0.1.1 2019/04/06 15:47 <DIR> shuworks.vscode-table-formatter-1.2.1 2019/04/06 15:47 <DIR> xyz.plsql-language-1.7.0 VSCodeの設定関連(キーバインドやその他設定等) settings.jsonに設定が記載されているのでこのファイルをコピーして終わりです。 C:\Users\ユーザー名\AppData\Roaming\Code\User ・settings.json --- ### GoldenGate 12.3新機能のParallel Replicatの動作を確認してみる date: 2019-04-29 url: https://zatoima.github.io/goldengate-parallel-replicat-try.html tags: Oracle, GoldenGate はじめに 前回の記事でParallel Replicatについて整理しました。 この記事では実機を使用した構築やプロセス、ログの出力の仕方を確認していきます。 今回作成するプロセスは「統合パラレルReplicat」になります。「非統合パラレルReplicat」の場合は別手順となりますのでご注意ください。 Integrated Parallel Replicatプロセス作成 プロセスは「parallel」句を付与します。統合モードの際は不要だった「checkpointtable」句を指定します。 GGSCI (dbvm1) 8> dblogin userid c##ggs@db18p1sv,password oracle Successfully logged into database DB18P1. GGSCI (dbvm1 as c##ggs@db18c2/DB18P1) 9> ADD REPLICAT r99,integrated,parallel EXTTRAIL ./dirdat/d11/rt checkpointtable c##ggs.ggckpt REPLICAT (Parallel) added. GGSCI (dbvm1 as c##ggs@db18c2/DB18P1) 11> info r99 REPLICAT R99 Initialized 2018-11-03 17:17 Status STOPPED INTEGRATED Parallel Checkpoint Lag 00:00:00 (updated 00:00:08 ago) Log Read Checkpoint File ./dirdat/d11/rt000000000 First Record RBA 0 Integrated Parallel Replicatパラメータ このパラメータでは「MAP_PARALLELISM」や「MIN_APPLY_PARALLELISM」、「MAX_APPLY_PARALLELISM」が統合パラレルReplicat特有のパラメータになります。 REPLICAT r99 USERID c##ggs@db18p1, PASSWORD oracle DISCARDFILE ./dirrpt/r99.dsc, APPEND, MEGABYTES 500 DISCARDROLLOVER AT 2:00 ON SUNDAY REPORTROLLOVER AT 2:00 ON SUNDAY MAP_PARALLELISM 3 MIN_APPLY_PARALLELISM 2 MAX_APPLY_PARALLELISM 8 -- BATCHSQL MAP ggtest.* ,TARGET db18p1.ggtest.*; Integrated Parallel Replicat起動時のggserr.log 2018-11-03T17:18:08.892+0900 INFO OGG-00987 Oracle GoldenGate Command Interpreter for Oracle: GGSCI command (oracle): start r99. 2018-11-03T17:18:08.905+0900 INFO OGG-00963 Oracle GoldenGate Manager for Oracle, mgr.prm: Command received from GGSCI on host [192.168.56.127]:47418 (START REPLICAT R99 ). 2018-11-03T17:18:08.934+0900 INFO OGG-00975 Oracle GoldenGate Manager for Oracle, mgr.prm: REPLICAT R99 starting. 2018-11-03T17:18:09.170+0900 INFO OGG-03059 Oracle GoldenGate Delivery for Oracle, r99.prm: Operating system character set identified as UTF-8. 2018-11-03T17:18:09.170+0900 INFO OGG-02695 Oracle GoldenGate Delivery for Oracle, r99.prm: ANSI SQL parameter syntax is usedfor parameter parsing. 2018-11-03T17:18:09.244+0900 INFO OGG-01360 Oracle GoldenGate Delivery for Oracle, r99.prm: REPLICAT is running in Parallel Integrated mode. 2018-11-03T17:18:11.117+0900 INFO OGG-06067 Oracle GoldenGate Delivery for Oracle, r99.prm: Spawned Applier with pid 32,269. 2018-11-03T17:18:11.125+0900 INFO OGG-06067 Oracle GoldenGate Delivery for Oracle, r99.prm: Spawned Applier with pid 32,270. 2018-11-03T17:18:11.137+0900 INFO OGG-06067 Oracle GoldenGate Delivery for Oracle, r99.prm: Spawned Mapper with pid 32,272. 2018-11-03T17:18:11.539+0900 INFO OGG-06067 Oracle GoldenGate Delivery for Oracle, r99.prm: Spawned Applier with pid 32,271. 2018-11-03T17:18:11.668+0900 INFO OGG-06067 Oracle GoldenGate Delivery for Oracle, r99.prm: Spawned Mapper with pid 32,285. 2018-11-03T17:18:11.668+0900 INFO OGG-06067 Oracle GoldenGate Delivery for Oracle, r99.prm: Spawned Applier with pid 32,286. 2018-11-03T17:18:11.766+0900 INFO OGG-06067 Oracle GoldenGate Delivery for Oracle, r99.prm: Spawned Mapper with pid 32,287. 2018-11-03T17:18:11.766+0900 INFO OGG-06067 Oracle GoldenGate Delivery for Oracle, r99.prm: Spawned Applier with pid 32,288. 2018-11-03T17:18:12.298+0900 INFO OGG-00995 Oracle GoldenGate Delivery for Oracle, r99.prm: REPLICAT R99A00 starting. Integrated Parallel Replicat起動中のggserr.log 負荷に応じてApplierプロセスが増減します。「MIN_APPLY_PARALLELISM」で指定したApplierプロセスは必ず確保します。 2018-11-03T17:46:44.808+0900 INFO OGG-06067 Oracle GoldenGate Delivery for Oracle, r99.prm: Spawned Applier with pid 17,035. 2018-11-03T17:46:48.465+0900 INFO OGG-02530 Oracle GoldenGate Delivery for Oracle, r99.prm.backup: Integrated replicat successfully attached to inbound server OGG$R99. 2018-11-03T17:51:54.641+0900 INFO OGG-06073 Oracle GoldenGate Delivery for Oracle, r99.prm: Removed Applier with pid 15,777. 2018-11-03T17:53:09.738+0900 INFO OGG-06073 Oracle GoldenGate Delivery for Oracle, r99.prm: Removed Applier with pid 15,780. 2018-11-03T17:54:24.872+0900 INFO OGG-06073 Oracle GoldenGate Delivery for Oracle, r99.prm: Removed Applier with pid 15,782. 2018-11-03T17:55:39.986+0900 INFO OGG-06073 Oracle GoldenGate Delivery for Oracle, r99.prm: Removed Applier with pid 15,783. Integrated Parallel ReplicatのOSのプロセス情報 OS上からは「R99Axx」、「R99Mxx」というプロセス名が起動されていることを確認できます。 oracle 32190 25849 0 17:17 pts/2 00:00:00 tail -f ggserr.log oracle 32259 26592 1 17:18 ? 00:00:01 /gg/gg181/replicat PARAMFILE /gg/gg181/dirprm/r99.prm REPORTFILE /gg/gg181/dirrpt/R99.rpt PROCESSID R99 oracle 32269 32259 0 17:18 ? 00:00:00 /gg/gg181/replicat PARAMFILE /gg/gg181/dirprm/r99.prm REPORTFILE /gg/gg181/dirrpt/R99.rpt PROCESSID R99A00 THREADID 0 PARAMCRC 3975171 oracle 32270 32259 0 17:18 ? 00:00:00 /gg/gg181/replicat PARAMFILE /gg/gg181/dirprm/r99.prm REPORTFILE /gg/gg181/dirrpt/R99.rpt PROCESSID R99A01 THREADID 1 PARAMCRC 3975171 oracle 32271 32259 0 17:18 ? 00:00:00 /gg/gg181/replicat PARAMFILE /gg/gg181/dirprm/r99.prm REPORTFILE /gg/gg181/dirrpt/R99.rpt PROCESSID R99A02 THREADID 2 PARAMCRC 3975171 oracle 32272 32259 0 17:18 ? 00:00:00 /gg/gg181/replicat PARAMFILE /gg/gg181/dirprm/r99.prm REPORTFILE /gg/gg181/dirrpt/R99.rpt PROCESSID R99M00 THREADID 0 PARAMCRC 3975171 oracle 32275 27681 0 17:18 ? 00:00:00 oracledb112n1 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq))) root 32277 2 0 17:18 ? 00:00:00 [kworker/u8:2] --- ### GoldenGate 12.3新機能のParallel Replicatの概要 date: 2019-04-28 url: https://zatoima.github.io/goldengate-parallel-replicat-overview.html tags: Oracle, GoldenGate はじめに 従来のReplicatのモードは「Classic Replicat」と「Integrated Replicat」の2つでした。GoldenGateの12.3以降のバージョンからReplicatの新モードであるParalell Replicatが登場しました。この新しい特徴を確認する限り従来のモードで実現出来なかったこと(特に性能問題)を解決出来るのでは、と感じています。 本記事では、概略レベルを整理して、次回の記事で具体的な動作を確認したいと思います。 概要 Parallel Replicatは、毎秒最大100万回以上の適用率を達成する、非常にスケーラブルな適用エンジンを備えています。 Integrated Replicatよりも5倍高速 単一の大きなトランザクションを並行して適用 データベース外での依存関係計算と並列処理 単一の大規模トランザクションを並列化する機能 大規模トランザクションを並列化している間も依存関係が考慮 トランザクション分割サイズ(レコード数)を指定するSPLIT_TRANS_RECSパラメータによって制御される機能。 デフォルトは100,000です。 参考 http://www.oracle-scn.com/oracle-goldengate-parallel-replicat/ Classic Replicat、及びIntegrated Replicatの場合、大規模なトランザクション(数千万件を更新後に1度だけcommitされる場合等)はレプリケーション遅延が起こりやすい処理でした。 上記の「単一の大規模トランザクションを並列化する機能」や「Integrated Replicatよりも5倍高速」という製品メッセージが事実であれば性能的に高速化が見込めます。 プロセス概略 マッパーはパラレルに動作し、証跡の読取り、証跡レコードのマッピング、マップされたレコードの統合Replicat LCR形式への変換、および後続の処理のためのマージャへのLCRの送信を実行します。 マスター・プロセスにはコレータとスケジューラの2つのスレッドがあります。コレータはマスターからマップされたトランザクションを受け取り、依存関係の計算のために証跡の順序に戻します。スケジューラがトランザクション間の依存関係を計算し、トランザクションを独立したバッチにグループ化し、ターゲット・データベースに適用するためにバッチをアプライアに送信します。 別モードの統合Replicatの場合はこのプロセスが「Reader」となっており、パラレルではなくシリアルです。 参考 こちらはIntegrated Repliatの場合です。Applierがパラレル化されるのは同一ですが、Applier以前のアーキテクチャが大きく違います。 プロセス作成方法 従来通りプロセス自体はADD Replicatコマンドで作成します。 ggsci > ADD REPLOCAT R1 , INTEGRATED , PARALLEL , EXTTRAIL ./dirdat/ra checkpointtable ggadmin.ggs_checkpoint 使用するパラメータ パラメータ 説明 MAP_PARALLELISM マッパーの数を構成します。これは証跡ファイルを読み取るために使用されるスレッドの数を制御します。最小値は1、最大値は100、デフォルトは2です。 APPLY_PARALLELISM アプライアの数を構成します。これは変更を適用するために使用されるターゲット・データベースの接続の数を制御します。デフォルト値は4です。 MIN_APPLY_PARALLELISM``MAX_APPLY_PARALLELISM 並列化の適用が自動チューニングされます。最小値と最大値を設定して、Replicatが並列化を自動的に調整する範囲を定義できます。デフォルト値はありません。APPLY_PARALLELISMと同時に使用しないでください。 SPLIT_TRANS_REC 大きなトランザクションを指定のサイズのピースに分割して、パラレルに適用するように指定します。ピース間の依存関係は保持されます。デフォルトでは無効です。 COMMIT_SERIALIZATION FULL直列化モードのコミットを有効にし、証跡の順序でトランザクションを強制的にコミットします。 高度なパラメータ LOOK_AHEAD_TRANSACTIONS トランザクションをバッチ化するときに、スケジューラがどの程度先まで対象にするかを制御します。デフォルト値は10000です。 CHUNK_SIZE 並列Replicatで、どの程度の大きさのトランザクションを大きいトランザクションとみなすかを制御します。並列Replicatは、このサイズより大きいトランザクションを検出すると、そのトランザクションをシリアライズするためにパフォーマンスが低下します。ただし、この値を大きくすると、並列Replicatによって消費されるメモリーも増加します。 その他注意事項 •Integrated Parallel Replicatの場合、COMMIT_SERIALIZATIONのFULLモードはサポートされていません。使用できるモードはデフォルトのDEPENDENTになります。 •DBのバージョンはターゲットが12.2以降である必要があります。 •並列Replicatは完全なメタデータを持つ証跡からのデータ・レプリケーションのみをサポートします。したがって、ソース側はGG12.2以降のバージョンを使用する必要があります。 --- ### ロングトランザクション時のGoldenGateのメモリの使用動作を検証する date: 2019-04-21 url: https://zatoima.github.io/goldengate-longtransaction-memoryuse.html tags: GoldenGate はじめに 以前、下記記事でGoldenGateのメモリの使い方について整理しました。 Oracle GoldenGateの仮想メモリの使い方を整理する - zato logger https://www.zatolog.com/entry/goldengate-vmemory-use 実際にロングトランザクションを実行してどのようにメモリを使用するのかを見える化したいと思います。 事前準備 CACHESIZEについて ソース側のCaptureに設定するCACHESIZEは「1GB」を設定しています。 情報取得対象 下記情報を1分ごとに取得するため簡易的なスクリプトを配置します。 取得する情報はこちらです。 取得先/取得コマンド 取得情報 v$sysstat REDO生成量 SEND EXTRACT <Capture名>, CACHEMGR CACHESTATS キャッシュマネージャー統計 info exttrail ./dirdat/c11/lt Trailファイル情報 情報取得スクリプト 1回しか使わないので雑です。 #!/bin/bash . "/home/oracle/.oraenv_db112s" while : do date sqlplus / as sysdba << EOF set pages 2000 lin 2000 col name for a20 select * from v\$sysstat where name = 'redo size'; exit EOF /gg/gg1/ggsci << EOF info exttrail ./dirdat/c11/lt SEND EXTRACT c11, CACHEMGR CACHESTATS exit EOF ls -lth /gg/gg1/BR/C11/stale ls -lth /gg/gg1/dirtmp sleep 60 done ソース側で流すトランザクション 一度もcommitせず、「20,000,000(2000万件)」ひたすらInsertを行います。貧弱な環境なのでUNDO表領域が枯渇やアーカイブログ領域やデータファイルのパンクの可能性がありますがトライしてみます。 create table memtest(a number primary key,b varchar2(30)); declare v_c1 number; v_c2 varchar2(30); begin dbms_random.seed(uid); for i in 1..20000000 loop v_c1 := i; v_c2 := dbms_random.string('x', 16); insert into reptest (a, b) values (v_c1, v_c2); end loop; commit; end; / 実行結果 REDO更新量、及びvm current(MB)、byte to disk(MB)をグラフ化しました。 CHCHESIZEの1GBを上限に「vm current」が推移している。 先日まとめた資料にCACHESIZEの上限値は弱い制限であり、トランザクションによってはCACHEMAXSIZEまで使用する可能性があると記載しました。今回のケースでは同様のトランザクション傾向のためこの弱い制限以上に仮想メモリを使用することは無さそうでした。 REDO生成量の「7~8割」がディスクのdirtmpにスワップしている。 約30分更新し続けており、REDO更新量(MB)は右肩上がりです。それに合わせてbytes to disk(MB)も追従する形で右肩上がりとなっています。 今回のケースでは約10GBのREDO生成量のロングトランザクションでしたが、実際の業務では大量バッチ更新等が行われる可能性があり、大量のREDO更新が見込まれます。どのくらいスワップ用のディレクトリを確保すべきか改めて考える必要があると思います。 更新完了後の「vm current」が0に減っている ロングトランザクションが完了してcommitが発行後にvm current(MB)の値が0になっています。確保されていた仮想メモリが開放されていることがわかります。ちなみに過去どのくらいの仮想メモリを使用したかの最大値を知りたい場合は「vm used max」で確認が出来ます。 --- ### Oracle GoldenGateの仮想メモリの使い方を整理する date: 2019-04-20 url: https://zatoima.github.io/goldengate-vmemory-use.html tags: GoldenGate, Oracle はじめに GoldenGateもOS上で動作するミドルウェアなので物理メモリ/仮想メモリを使用します。 GoldenGateはコミットされたトランザクションのみをレプリケートするため、トランザクションのコミットまたはロールバックを受信するまで、キャッシュと呼ばれる管理仮想メモリー・プールに各トランザクションの操作を保持する必要があります。ここで述べているのは物理メモリではなく仮想メモリです。ご注意ください。 本記事で明示的に指定していない場合は、メモリという言葉は仮想メモリを指します。 GoldenGateプロセスによって使用される物理メモリーの実際の量は、オペレーティング・システムによって制御されます。 具体的なメモリの使い方と使用されるスワップ容量については本記事では扱いません。 必要な仮想メモリ量について 仮想メモリの見積もり式は下記の通りマニュアルに記載があります。 https://docs.oracle.com/cd/E74358_01/gg-winux/GWURF/GUID-B910F3D9-E41C-4335-AC0A-442435481A19.htm CACHEMGR 1. 1つのExtractプロセスおよび1つのReplicatプロセスを起動します。 2. GGSCIを実行します。 3. 実行中の各プロセスのレポート・ファイルを表示し、PROCESS VM AVAIL FROM OS (min)行を探します。 4. 必要な場合、各値を次の整数(GB)に切り上げます。たとえば、1.76GBの場合は2GBに切り上げます。 5. 繰り上げられたExtractの値に、Extractプロセスの数を掛けます。 6. 繰り上げられたReplicatの値に、Replicatプロセスの数を掛けます。 7. 2つの結果に、システム上のOracle GoldenGateプロセスおよびその他のプロセスで必要とする追加スワップ領域を足します。 (PROCESS_VM x number_Extracts) + (PROCESS_VM x number_Replicats) + (swap_for_other_processes) = max_swap_space_on_system この合計が、これらのプロセスに必要な最大スワップ領域になります。すべてのOracle GoldenGateプロセスが使用する実際の物理メモリー量は、Oracle GoldenGateプロセスではなく、オペレーティング・システムによって制御されます。グローバル・キャッシュ・サイズは、CACHEMGRのCACHESIZEオプションで制御します。 仮想メモリ動作 下記はプロセス起動時にレポートファイルに出力されるメモリの統計値です。 CACHEMGR virtual memory values (may have been adjusted) CACHEPAGEOUTSIZE (default): 4M PROCESS VM AVAIL FROM OS (min): 2G CACHESIZEMAX (strict force to disk): 1.74G 仮想メモリ上限値を設定したい場合、CACHESIZEパラメータを設定します。これはプロセスがトランザクション・データのキャッシュに使用できる仮想メモリーの弱い制限を示します。これは、PROCESS VM AVAIL FROM OS (min)の値に基づいて動的に決定されます。CACHEMGRのCACHESIZEオプションを使用して制御できます。トランザクション・データのキャッシングにできる仮想メモリー量(キャッシュ・サイズ)の弱い制限を指定するため、トランザクションによってはこのサイズを超えてメモリを使用するケースも存在します。この場合、上限値は上記の統計値で言うところの CACHESIZEMAXが上限となります。 次に、PROCESS VM AVAIL FROM OS (min)は、このプロセスが使用可能と判断したおおよその仮想メモリー量を示します。内部的な理由で、この量はオペレーティング・システムによって使用可能と表示される量より少ない場合があります。 CACHESIZEMAX (strict force to disk)は、PROCESS VM AVAIL FROM OSおよびCACHESIZEから導出されます。通常は、現在仮想メモリー・バッファが特定の内部値を超えているトランザクションのみがページングの候補です。メモリー・リクエストの合計がCACHESIZEの値を超えると、キャッシュ・マネージャはディスクに書き込むトランザクションを探し、ページング候補のリストからトランザクションを選択します。ページング候補のトランザクションがすでにディスクにページングされていて、使用中の仮想メモリーがCACHESIZEMAX (strict force to disk)を超えている場合は、追加のバッファを必要とするすべてのトランザクションをページング候補にできます。このような方法で、常に仮想メモリーの可用性が確保されています。 メモリ使用の上限を超える場合 GoldenGateインストール・ディレクトリのdirtmpサブディレクトリにトランザクション・データがスワップされます。 ロングトランザクションが実行される場合は設定しているCACHESIZE次第ですが、ディスクにスワップされる可能性が高いでディスク容量にも注意が必要と思われます。 SEND EXTRACT <Capture名>, CACHEMGR CACHESTATSについて 仮想メモリの使用状況について確認したい場合は下記コマンドを実行します。 多くの情報が出力されますが、「CACHE OBJECT MANAGER statistics」セクションを見てどのようなメモリ動作になっているか確認すれば良いと思います。ファイルキャッシュに関する情報は「CACHE File Caching」で確認可能です。 GGSCI (dbvgg.jp.oracle.com as ggs@db112s) 40> SEND EXTRACT c11, CACHEMGR CACHESTATS Sending CACHEMGR request to EXTRACT C11 ... CACHE OBJECT MANAGER statistics CACHE MANAGER VM USAGE vm current = 0 vm anon queues = 0 vm anon in use = 0 vm file = 0 vm used max = 1.27G ==> CACHE BALANCED CACHE CONFIGURATION cache size = 1G cache force paging = 1.74G buffer min = 64K buffer max (soft) = 4M pageout eligible size = 4M ================================================================================ RUNTIME STATS FOR SUPERPOOL CACHE Transaction Stats trans active = 0 max concurrent = 238 non-zero total = 1 trans total = 42.58K CACHE File Caching filecache rqsts = 129 bytes to disk = 8.20G file retrieves = 2.08K objs filecached = 1 queue entries = 129 queue processed = 130 queue entry not needed = 0 queue not signaled = 0 fc requesting obj = 0 CACHE MANAGEMENT buffer links = 2.06K anon gets = 0 forced unmaps = 39 cnnbl try = 200 cached out = 114 想定より多く仮想メモリを使用していることを疑われる場合はCACHE MANAGER VM USAGE を優先的に確認するのが良いと思います。 CACHE MANAGER VM USAGE vm current = 1015M vm anon queues = 320M vm anon in use = 692M vm file = 3M vm used max = 1G ==> CACHE BALANCED 各項目の補足説明 vm current : 現在割当てられている仮想メモリサイズ総量(メモリ+ページング) vm anon queues : vm current のうち、フリーなメモリサイズ(使用されなくなったメモリをフリーなメモリとして一旦キューに保持しているサイズ) vm anon in use : 現在処理で利用中の仮想メモリサイズ総量 vm file : 現在ページングしているサイズ vm used max : これまでに利用された仮想メモリサイズ総量の最大サイズ --- ### GoldenGate Classic Replicatプロセスが適用するSQLの10046トレース取得方法 date: 2019-04-17 url: https://zatoima.github.io/goldengate-classic-replicat-trace.html tags: Oracle, GoldenGate はじめに GoldenGateのReplicatプロセスが適用するSQLの調査をする場面があります。SQLの性能調査の場合はSQLトレースを取得して解析という流れになると思いますが、DB層からの操作ではGoldenGateセッション単位での設定は出来ないので、DB単位で設定する必要があります。 一方、GoldenGateにはSQLEXECというパラメータが用意されてありますので、こちらをReplicatプロセスのパラメータ・ファイルに記載することでReplicatが適用するSQLのみ10046トレースが取得が可能です。 SQLEXEC https://docs.oracle.com/cd/E51849_01/gg-winux/GWURF/gg_parameters156.htm SQLEXECパラメータでは、Oracle GoldenGate処理の範囲でストアド・プロシージャ、問合せまたはデータベース・コマンドを実行します。SQLEXECにより、Oracle GoldenGateはデータベースと直接通信し、データベースによってサポートされている処理を実行できます。 設定方法 ~省略~ REPORTCOUNT EVERY 10 MINUTES, RATE SQLEXEC "ALTER SESSION SET TRACEFILE_IDENTIFIER='GG_DEBUG'" SQLEXEC "alter session set events '10046 trace name context forever,level 12'" BATCHSQL MAP ggtest.* ,TARGET db18p1.ggtest.*; ~省略~ ※この方法で10046トレースが取得できるのはClassic Replicatの場合のみです。Integrated Replicatでは他の方法を使用してSQL性能情報を取得する必要があります。 実行結果 TRACEFILE_IDENTIFIERで「GG_DEBUG」を付与しているため、トレースファイルには「GG_DEBUG」がついたファイルが生成されます。 [oracle@dbvgg trace]$ pwd /u01/app/oracle/diag/rdbms/db18s/db18s/trace [oracle@dbvgg trace]$ ls -ltr | tail -rw-r----- 1 oracle oinstall 1737 4月 3 10:49 2019 db18s_m000_3762.trm -rw-r----- 1 oracle oinstall 8661 4月 3 10:49 2019 db18s_m000_3762.trc -rw-r----- 1 oracle oinstall 1160 4月 3 10:49 2019 db18s_dbrm_3705.trm -rw-r----- 1 oracle oinstall 4775 4月 3 10:49 2019 db18s_dbrm_3705.trc -rw-r----- 1 oracle oinstall 1646 4月 3 10:50 2019 db18s_m003_4089.trm -rw-r----- 1 oracle oinstall 7495 4月 3 10:50 2019 db18s_m003_4089.trc -rw-r----- 1 oracle oinstall 1894 4月 3 10:50 2019 db18s_m002_4087.trm -rw-r----- 1 oracle oinstall 11111 4月 3 10:50 2019 db18s_m002_4087.trc -rw-r----- 1 oracle oinstall 234008 4月 3 10:50 2019 db18s_ora_5208_GG_DEBUG.trm -rw-r----- 1 oracle oinstall 1339711 4月 3 10:50 2019 db18s_ora_5208_GG_DEBUG.trc [oracle@dbvgg trace]$ --- ### VSCodeで10000行以上の矩形選択を行った場合に「カーソルの数は10000個に制限されています」が出力される date: 2019-04-14 url: https://zatoima.github.io/vscode-eectangular-selection-cursol-error.html tags: VSCode はじめに VSCode使いやすいですよね。長らくSublime text3を使用していましたが、Windows10の「IMESupport」の動作が色々と耐えられなかったのでVSCodeに乗り換えました。 VSCodeはメールの下書きを作成するようのテキストエディタ(たまにコードも書く)だけではなくCSVや各種ログを参照するのにも使っています。ログやCSVを整形する時に1万行以上の矩形選択をすることもあるのですが、VSCodeの場合は下記エラーメッセージが出力されます。 原因 下記のコードのように"MAX_CURSOR_COUNT"でハードコーディングされているため1万行以上の矩形選択は出来ない模様です。 [GitHub]Microsoft/vscode: Visual Studio Code public static MAX_CURSOR_COUNT = 10000; 回避策 ネット上で調査する限り回避策はありませんでした。他のエディタを使いましょう。 備考 本件はteratailで質問した際の回答で教えて頂きました。 Visual Studio Code - vscodeの矩形選択で「カーソルの数は 10000 個に制限されています。」が出力される|teratail https://teratail.com/questions/161064 --- ### フル・トランスポータブル表領域実施時にORA-31633、ORA-01647で失敗する date: 2019-04-12 url: https://zatoima.github.io/oracle-full-tts-oraerror.html tags: Oracle はじめに フル・トランスポータブル・エクスポート/インポート機能を使用すると、データベース全体を異なるデータベース・インスタンスに移動できます。 データベース全体のデータを移行できるので、移行先のデータベースでインデックスや各種オブジェクト(プロシージャ・パッケージ…etc)を別途作成する必要がありません。 また、トランスポータブル表領域(TTS)と同様にデータファイルは物理コピーが可能ですので、中間ファイル作成等の操作が必要ありません。Data Pumpと比較すると高速な手法と言えます。(メタデータは別途エクスポートが必要です。) 下記のホワイトペーパーも合わせてご確認ください。 https://www.oracle.com/technetwork/jp/database/enterprise-edition/full-transportable-wp-12c-1973971-ja.pdf > Oracle Database 12c:フル・トランスポータブル・エクスポート/インポート 手順概要 ソース・データベースで、各ユーザー定義表領域を読取り専用モードにし、データベースをエクスポートします。 ・次のパラメータが指定された値に設定されていることを確認します。 TRANSPORTABLE=ALWAYS FULL=Y ・ソース・データベースがOracle Database 11g リリース2 (11.2.0.3)またはOracle Database 11g以上の データベースである場合、VERSIONパラメータを12以上に設定する必要があります。 ・ソース・データベースに暗号化された表領域、または暗号化された列を含む表が格納された表領域が含まれている場合は、ENCRYPTION_PWD_PROMPT=YESを指定するか、ENCRYPTION_PASSWORDパラメータを指定する必要があります。 ・エクスポート・ダンプ・ファイルには、ユーザー定義表領域に格納されたオブジェクトのメタデータ、および管理表領域(SYSTEMやSYSAUXなど)に格納されたユーザー定義オブジェクトのメタデータとデータの両方が含まれています。 エラー内容 上記の手順概要の通り、ユーザ表領域を読み取り専用にしてTRANSPORTABLE=ALWAYS、及びFULL=Yを指定してexpdpを実行したところORA-31633、及びORA-01647が発生してエラーになります。 [oracle@dbvop]$ expdp DPUSR/oracle full=y transportable=always directory=dp_dir dumpfile=full_tts.dmp encryption_password=oracle logfile=full_tts_export.log Export: Release 12.1.0.2.0 - Production on 水 3月 13 15:04:08 2019 Copyright (c) 1982, 2014, Oracle and/or its affiliates. All rights reserved. 接続先: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production With the Partitioning, Real Application Clusters, Oracle Label Security, OLAP, Advanced Analytics, Oracle Database Vault and Real Application Testing options ORA-31626: ジョブが存在しません ORA-31633: マスター表"DPUSR.SYS_EXPORT_FULL_07"を作成できません ORA-06512: "SYS.DBMS_SYS_ERROR", 行95 ORA-06512: "SYS.KUPV$FT", 行1048 ORA-01647: 表領域'USERS'は読取り専用です。領域を割当てできません 原因 下記マニュアルの制限に引っ掛かったことが原因と考えられます。 https://docs.oracle.com/cd/E57425_01/121/SUTIL/GUID-206EC89B-5E43-4CCF-8B78-2C7F91FC5D7D.htm TRANSPORT_TABLESPACES エクスポートを実行するユーザーのデフォルトの表領域を、転送対象となっている表領域のいずれかに設定することはできません。 ホワイトペーパーやマニュアルの手順では「system」ユーザで実行されており、systemユーザのデフォルト表領域は「SYSAUX」となります。 今回はData Pump専用のDPUSRで実行していました。このユーザは、「ユーザ表領域」をデフォルト表領域に設定していたため、エラーになりました。 回避方法 下記2つのどちらかです。 SYSやSYSTEMユーザで実行する Data Pump専用のDPUSRのデフォルト表領域を一時的に「SYSAUX」に変更する --- ### GoldenGateのClassic Replicat(非統合Replicat)の作成手順 date: 2019-04-10 url: https://zatoima.github.io/goldengate-classic-replicat-create.html tags: Oracle, GoldenGate 他記事でIntegrated Replicat(統合Replicat)のプロセス構成手順は記載しました。ただ、Classic Replicat(非統合Replicat)も使用することが多いので手順を記載します。 手順の違いはコマンドの引数(オプション)が変わるということとチェックポイント表の作成が必要ということです。内部的な動作は多く変わっているのでそこは別途注意が必要かと思います。 ターゲット側にてClassic Replicatプロセスを作成 パラメータファイル作成 . /home/oracle/.oraenv_db18s --環境変数の読み込み cd /gg/gg2 ./ggsci #パラメータ作成 edit param r21 下記パラメータを設定する ---- REPLICAT R21 USERID c##ggs@db18p1, PASSWORD oracle DISCARDFILE ./dirrpt/r21.dsc, APPEND, MEGABYTES 500 DISCARDROLLOVER AT 2:00 ON SUNDAY REPORTROLLOVER AT 2:00 ON SUNDAY BATCHSQL MAP ggtest.* ,TARGET db18p1.ggtest.*; ---- view param r21 Replicatプロセスの作成 #DBログイン dblogin userid c##ggs@db18p1,password oracle #Replicatプロセスの作成 add replicat r21, exttrail ./dirdat/d11/rt, CHECKPOINTTABLE c##ggs.ggs_ckpt #チェックポイントファイルの作成 ADD CHECKPOINTTABLE c##ggs.ggs_ckpt INFO CHECKPOINTTABLE c##ggs.ggs_ckpt #実行結果 GSCI (dbvgg.jp.oracle.com as c##ggs@db18s/DB18P1) 4> add replicat r11, exttrail ./dirdat/d11/rt, CHECKPOINTTABLE c##ggs.ggs_ckpt REPLICAT added. GGSCI (dbvgg.jp.oracle.com as c##ggs@db18s/DB18P1) 5> add checkpointtable ERROR: Missing checkpoint table specification. GGSCI (dbvgg.jp.oracle.com as c##ggs@db18s/DB18P1) 6> GGSCI (dbvgg.jp.oracle.com as c##ggs@db18s/DB18P1) 6> ADD CHECKPOINTTABLE c##ggs.ggs_ckpt Logon catalog name DB18P1 will be used for table specification DB18P1.c##ggs.ggs_ckpt. Successfully created checkpoint table DB18P1.c##ggs.ggs_ckpt. GGSCI (dbvgg.jp.oracle.com as c##ggs@db18s/DB18P1) 7> info checkpointtable c##ggs.ggs_ckpt Logon catalog name DB18P1 will be used for table specification DB18P1.c##ggs.ggs_ckpt. Checkpoint table DB18P1.c##ggs.ggs_ckpt created 2019-04-03 10:33:15. 各プロセスの作成手順のマニュアルはこちらです。 https://docs.oracle.com/cd/E74358_01/gg-winux/GIORA/GUID-7065CF34-FD9A-4652-A34A-AE9F6BD3C87E.htm > Replicatグループの追加 Classic Replicatを使用する場合はチェックポイント表の理解も重要です。こちらのマニュアルの記載をご参照ください。 https://docs.oracle.com/cd/E74358_01/gg-winux/GIORA/GUID-B3EFA08D-145B-4806-B7E2-B8AE409C651C.htm#GUID-B3EFA08D-145B-4806-B7E2-B8AE409C651C > チェックポイント表の作成(非統合Replicatのみ) https://docs.oracle.com/cd/E74358_01/gg-winux/GWUAD/GUID-D1ED9CCF-C81C-4CE2-8EAB-E4C8C7BDF58C.htm > Oracle GoldenGateチェックポイント表 --- ### 実行中のGoldenGateプロセスのパラメータの情報取得 date: 2019-04-06 url: https://zatoima.github.io/goldengate-gg-process-getparaminfo.html tags: GoldenGate 実行中のプロセスのパラメータを取得する方法。意図的に設定したパラメータ、左記以外のパラメータも出力されるため合わせてご確認ください。 マニュアルはこちらです。 https://docs.oracle.com/cd/E74358_01/gg-winux/GWURF/GUID-6D0E4481-BB8A-4B3C-B8E9-2305BC01928E.htm GETPARAMINFO GETPARAMINFOでは、Extract、Replicat、Manageなどの実行中のインスタンスのランタイム・パラメータ値を問い合せます。1つまたはすべてのパラメータを問い合せて、出力をコンソールまたはテキスト・ファイルに送信できます。 MGRプロセス GGSCI (node1.oracle12c.jp) 1> send MGR getparaminfo Sending GETPARAMINFO request to MANAGER ... GLOBALS checkpointtable : c##ggs.ggs_ckpt enablemonitoring : <enabled> /u01/ogg_1/dirprm/mgr.prm port : 7809 purgeoldextracts : /u01/ogg_1/dirdat Default Values ptkcaptureprocstats : <enabled> ptkmonitorfrequency : 1 ptkprocesscheckfrequency : 1 checkminutes : 10 monitoring_heartbeat_timeout : 10 usecheckpoints : <enabled> minkeepfiles : 1 frequencyminutes : 60 repobackupdir : dirbkup repobackupfrequency : 0 reponumbackupsbeforefullbackup : 3 Captureプロセス GGSCI (node1.oracle12c.jp) 2> send cap01 getparaminfo Sending GETPARAMINFO request to EXTRACT CAP01 ... GLOBALS checkpointtable : c##ggs.ggs_ckpt enablemonitoring : <enabled> /u01/ogg_1/dirprm/cap01.prm extract : CAP01 logallsupcols : <enabled> setenv : (ORACLE_HOME=/u01/app/oracle/product/12.1.0/dbhome_1) setenv : (ORACLE_SID=cdb1) userid : c##ggs password : ******* updaterecordformat : COMPACT ddl : <enabled> include : <enabled> : <enabled> mapped : <enabled> : <enabled> sourcecatalog : p_pdb1 : p_pdb2 exttrail : ./dirdat/local/lt table : p_pdb1.oracle.* table : p_pdb2.oracle.* sourcecatalog : p_pdb1 table : oracle.* sourcecatalog : p_pdb2 Default Values deletelogrecs : <enabled> fetchoptions : userowid : <enabled> usekey : <enabled> missingrow : ALLOW usesnapshot : <enabled> uselatestversion : <enabled> maxfetchstatements : 100 usediagnostics : <disabled> detaileddiagnostics : <disabled> diagnosticsonall : <disabled> nosuppressduplicates : <enabled> flushsecs : 1 passthrumessages : <enabled> ptkcapturecachemgr : <enabled> ptkcaptureift : <enabled> ptkcapturenetwork : <enabled> ptkcapturequeuestats : <enabled> ptkspstats : <enabled> tcpsourcetimer : <enabled> warnlongtrans : 3600 second(s) retrydelay : 60 allocfiles : 500 allowduptargetmap : <disabled> binarychars : <enabled> checkpointsecs : 10 second(s) cmdtrace : OFF dynamicresolution : <enabled> eofdelay : 1 eofdelaycsecs : 100 functionstacksize : 200 numfiles : 1000 ptkcapturetablestats : <enabled> ptkmaxtables : 100 ptktablepollfrequency : 1 varwidthnchar : <disabled> enableheartbeat : <enabled> ptkcaptureprocstats : <enabled> ptkmonitorfrequency : 1 use_traildefs : <enabled> Data Pumpプロセス GGSCI (node1.oracle12c.jp) 3> send dp01 getparaminfo Sending GETPARAMINFO request to EXTRACT DP01 ... GLOBALS checkpointtable : c##ggs.ggs_ckpt enablemonitoring : <enabled> /u01/ogg_1/dirprm/dp01.prm extract : DP01 passthru : <enabled> rmthost : node1.oracle12c.jp mgrport : 7810 rmttrail : /u01/ogg_2/dirdat/remote/rt table : p_pdb1.oracle.* table : p_pdb2.oracle.* Default Values deletelogrecs : <enabled> fetchoptions : userowid : <enabled> usekey : <enabled> missingrow : ALLOW usesnapshot : <enabled> uselatestversion : <enabled> maxfetchstatements : 100 usediagnostics : <disabled> detaileddiagnostics : <disabled> diagnosticsonall : <disabled> nosuppressduplicates : <enabled> flushsecs : 1 passthrumessages : <enabled> ptkcapturecachemgr : <enabled> ptkcaptureift : <enabled> ptkcapturenetwork : <enabled> ptkcapturequeuestats : <enabled> ptkspstats : <enabled> rmthost : port : 7819 timeout : 300 tcpsourcetimer : <enabled> warnlongtrans : 3600 second(s) retrydelay : 60 allocfiles : 500 allowduptargetmap : <disabled> binarychars : <enabled> checkpointsecs : 10 second(s) cmdtrace : OFF dynamicresolution : <enabled> eofdelay : 1 eofdelaycsecs : 100 functionstacksize : 200 numfiles : 1000 ptkcapturetablestats : <enabled> ptkmaxtables : 100 ptktablepollfrequency : 1 varwidthnchar : <disabled> enableheartbeat : <enabled> ptkcaptureprocstats : <enabled> ptkmonitorfrequency : 1 use_traildefs : <enabled> Replicatプロセス GGSCI (node1.oracle12c.jp) 1> send rep01 getparaminfo Sending GETPARAMINFO request to REPLICAT REP01 ... GLOBALS checkpointtable : c##ggs.ggs_ckpt enablemonitoring : <enabled> /u01/ogg_2/dirprm/rep01.prm replicat : REP01 setenv : ("ORACLE_HOME=/u01/app/oracle/product/12.1.0/dbhome_1") setenv : (ORACLE_SID=cdb2) userid : c##ggs@s_pdb1 password : ******* assumetargetdefs : <enabled> discardfile : ./dirrpt/REP01.DSC purge : <enabled> map : p_pdb1.oracle.* target : s_pdb1.oracle.* Default Values allownoopupdates : <disabled> applynoopupdates : <disabled> auditreps : <enabled> deferapplyinterval : 0 FILESEQNO grouptransops : 50 maxdiscardrecs : 0 maxsqlstatements : 250 ptkcapturebatchsql : <enabled> ptkirstatsfrequency : 10 restartcollisions : <disabled> retrydelay : 60 warnrate : 100 allocfiles : 500 allowduptargetmap : <disabled> binarychars : <enabled> checkpointsecs : 10 FILESEQNO cmdtrace : OFF dynamicresolution : <enabled> eofdelay : 1 eofdelaycsecs : 100 functionstacksize : 200 numfiles : 1000 ptkcapturetablestats : <enabled> ptkmaxtables : 100 ptktablepollfrequency : 1 varwidthnchar : <disabled> enableheartbeat : <enabled> ptkcaptureprocstats : <enabled> ptkmonitorfrequency : 1 use_traildefs : <enabled> --- ### GoldenGateのコマンドを使用してオープントランザクションを特定する date: 2019-04-05 url: https://zatoima.github.io/goldengate-opentransaction-getinfo.html tags: Oracle, GoldenGate showtransオプションを使用するとオープントランザクションの情報が出力される XIDを把握します。 GGSCI (dbvgg.jp.oracle.com) 2> send c11,showtrans Sending SHOWTRANS request to EXTRACT C11 ... ------------------------------------------------------------ XID: 5.15.930 Items: 1 Extract: C11 Redo Thread: 1 Start Time: 2019-03-29:22:00:35 SCN: 0.1124828 (1124828) Redo Seq: 10 Redo RBA: 122960912 Status: Running 稼動しているトランザクションを見る方法 SES_ADDRが判明します。 SQL> select SES_ADDR,XIDUSN, XIDSLOT, XIDSQN, START_SCN from v$transaction; SES_ADDR XIDUSN XIDSLOT XIDSQN START_SCN 000000010868F4E0 5 15 930 1124828 SQL> 特定のトランザクションが動いているセッションを知る方法 SES_ADDRをv$sessionのsaddrに指定します。 SQL> select sid,serial#,username,logon_time,status 2 from v$session 3 where saddr='000000010868F4E0'; SID SERIAL# USERNAME LOGON_TIME STATUS 18 1117 GGTEST 19-03-29 INACTIVE SQL_ID、SQL_TEXTを確認する方法 sid,serial#を基にSQL_TEXTを確認します。 SQL> SELECT 2 s.sid, 3 s.serial#, 4 s.status, 5 s.machine, 6 s.osuser, 7 s.module, 8 s.username, 9 s.process, 10 p.program, 11 a.sql_text 12 FROM v$session s, 13 v$sqlarea a, 14 v$process p 15 WHERE s.PREV_HASH_VALUE = a.hash_value 16 AND s.PREV_SQL_ADDR = a.address 17 AND s.paddr = p.addr 18 AND s.SID = 18; SID SERIAL# STATUS MACHINE OSUSER MODULE USERNAME PROCESS PROGRAM SQL_TEXT 18 1117 INACTIVE dbvgg.jp.oracle.com oracle SQL*Plus GGTEST 11342 oracle@dbvgg.jp.oracle.com (TNS V1-V3) insert into t1 values (TO_NUMBER(TO_CHAR(SYSTIMESTAMP, 'YYYYMMDDHH24MISSFF4')),dbms_flashback.get_system_change_number,'test',sysdate) マニュアルはこちらです。send extractには便利なオプションがたくさんありますのでご確認ください。 https://docs.oracle.com/cd/E51849_01/gg-winux/GWURF/ggsci_commands014.htm SEND EXTRACT SHOWTRANS オープンしているトランザクションに関する情報を表示します。SHOWTRANSは、データベース・タイプに応じて次のいずれかを表示します。 プロセス・チェックポイント(Extractが再起動する場合に、トランザクション処理を継続する必要がある最も古いログを示します)。チェックポイントの詳細は、Oracle GoldenGateの管理for Windows and UNIXを参照してください。 トランザクションID Extractグループ名 REDOスレッド番号 (トランザクションの実際の開始時刻でなく)Oracle GoldenGateがトランザクションから抽出した最初の操作のタイムスタンプ システム変更番号(SCN) REDOログ番号とRBA ステータス(Pending COMMITまたはRunning)。Pending COMMITは、FORCETRANS発行後のトランザクション書込み中に表示されます。 オプションを指定しない場合SHOWTRANSでは、使用可能なバッファに収まるオープンしているすべてのトランザクションが表示されます。SHOWTRANSのサンプル出力は、例1-0を参照してください。出力をさらに制御するには、次のオプションを参照してください。 --- ### Oracle Databaseに新元号の「令和」を追加する date: 2019-04-01 url: https://zatoima.github.io/oracle-era-gengou-add.html tags: Oracle 新元号が発表されました。平成元年生まれなので平成の終わりがもうすぐ訪れると思うと色々と寂しいです。 元号使用の設定確認 西暦を使用している場合 SQL> SHOW PARAMETER nls_calendar NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ nls_calendar string GREGORIAN ←★西暦を使用 和暦を使用している場合 SQL> SHOW PARAMETER nls_calendar NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ nls_calendar string Japanese Imperial ←★和暦を使用 変更前の環境で元号を表示 下記の通り、「2019年5月1日」の改元時においても当然平成表示のままです。 show parameter NLS_CALENDAR ALTER SESSION SET NLS_CALENDAR="Japanese Imperial"; select sysdate+30 from dual; SQL> show parameter NLS_CALENDAR NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ nls_calendar string GREGORIAN SQL> ALTER SESSION SET NLS_CALENDAR="Japanese Imperial"; セッションが変更されました。 SQL> SQL> select sysdate+30 from dual; SYSDATE+30 --------------------------------------------- 平成31年05月01日 元号の設定追加 新元号名のEUCの16進コードを確認します。後続の手順で16進数で使用します。 SELECT DUMP(CONVERT('令和','JA16EUC'),16) AS "元号" FROM DUAL; SQL> SELECT DUMP(CONVERT('令和','JA16EUC'),16) AS "元号" FROM DUAL; 元号 ------------------------ Typ=1 Len=4: ce,e1,cf,c2 select dump('R',16) as "アルファベット" from dual; SQL> select dump('R',16) as "アルファベット" from dual; アルファベット ---------------- Typ=96 Len=1: 52 $ORACLE_HOME/nls に lxecal.nlt 設定ファイルを作成します。 DEFINE calendar calendar_name = "Japanese Imperial" DEFINE calendar_era era_full_name = "cee1cfc2" ★★令和 <====上記で確認した「元号」のEUC の16進コードをここに記述します era_abbr_name = "52" ★★令和 <=====上記で確認した「アルファベット」の EUC の16進コードをここに記述します start_date = "MAY-01-2019 AD" end_date = "DEC-31-2099 AD" ENDDEFINE calendar_era ENDDEFINE calendar [oracle@dbvgg ~]$ cd $ORACLE_HOME/nls [oracle@dbvgg nls]$ [oracle@dbvgg nls]$ ll 合計 32 drwxr-xr-x 3 oracle oinstall 4096 3月 22 02:09 2019 csscan drwxr-xr-x 3 oracle oinstall 20480 3月 22 02:09 2019 data drwxr-xr-x 3 oracle oinstall 4096 3月 22 02:10 2019 lbuilder drwxr-xr-x 2 oracle oinstall 4096 3月 22 02:09 2019 mesg [oracle@dbvgg nls]$ [oracle@dbvgg nls]$ vi lxecal.nlt [oracle@dbvgg nls]$ cat lxecal.nlt DEFINE calendar calendar_name = "Japanese Imperial" DEFINE calendar_era era_full_name = "cee1cfc2" era_abbr_name = "52" start_date = "MAY-01-2019 AD" end_date = "DEC-31-2099 AD" ENDDEFINE calendar_era ENDDEFINE calendar [oracle@dbvgg nls]$ データベースを停止後にlxegen を実行して lxecalji.nlb が作成されていることを確認します [oracle@dbvgg nls]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.4.0 Production on 月 4月 1 11:58:10 2019 Copyright (c) 1982, 2013, Oracle. All rights reserved. Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options に接続されました。 SQL> shutdown immediate データベースがクローズされました。 データベースがディスマウントされました。 ORACLEインスタンスがシャットダウンされました。 SQL> SQL> Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing optionsとの接続が切断されました。 [oracle@dbvgg nls]$ [oracle@dbvgg nls]$ lxegen NLS Calendar Utility: Version 11.2.0.4.0 - Production Copyright (c) Oracle 1994, 2004. All rights reserved. CORE 11.2.0.4.0 Production [oracle@dbvgg nls]$ 変更後の環境で元号を表示 再起動後は、「2019年5月1日」が新元号の「令和」表記になりました。 show parameter NLS_CALENDAR ALTER SESSION SET NLS_CALENDAR="Japanese Imperial"; select sysdate+30 from dual; SQL> show parameter NLS_CALENDAR NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ nls_calendar string GREGORIAN SQL> ALTER SESSION SET NLS_CALENDAR="Japanese Imperial"; セッションが変更されました。 SQL> SQL> select sysdate+30 from dual; SYSDATE+30 --------------------------------------------- 令和01年05月01日 備考 システム停止が必要のため、運用中のシステムは気軽に変更出来るものではないですね。 そもそも使っているところあるの? 参考URL こちらを全面的に参考にさせて頂きました。 Oracle 製品における改元の影響について | NTTデータ先端技術株式会社 http://www.intellilink.co.jp/article/column/ora-report20180604.html Oracle Databaseの新元号への対応について | アシスト https://www.ashisuto.co.jp/support/gengo/product/oracle-database.html https://qiita.com/ora_gonsuke777/items/dc21ee3f2abf718098b9 Oracle Database に 新しい元号(年号)「野球」を追加してみる。(NLSカレンダ・ユーティリティlxegen) --- ### expdp時にFLASHBACK_SCNを使用した場合のインスタンス化SCNについて date: 2019-03-30 url: https://zatoima.github.io/goldengate-flashbackscn-instantiationSCN.html tags: Oracle, GoldenGate はじめに GoldenGateにはインスタンス化SCNという機能があります。この機能を使用するとDatapumpを使用したシステム無停止の初期移行が簡単に出来ます。 詳細は下記のqiita記事がわかりやすいのでご確認ください。 インスタンス化SCNを使ってお手軽初期移行 - Qiita https://qiita.com/kurouuuron/items/118afdc6b6d15d46e7dd Oracle Datapump との連携を強化した、GoldenGateの初期移行用の機能。 一言でいえば、Datapumpを使用したシステム無停止の初期移行が簡単にできる、という機能。 もう少し言えば、Flashback_scnやHandlecollisionsなどの初期移行で考慮すべきポイントを考慮せずによくしてくれた機能。 実際の挙動としては、Datapumpでexpdpした際に、その表はどのSCNまで反映し終わっているか、というデータを内部的に付与してくれて、impdpしたらReplicatがそのSCN以降のデータから自動で当ててくれる、というもの。 この記事にもあるようにGoldenGate12.2以上でadd trandataを実行した場合にpreparescnがデフォルトで付与されるためDatapumpでexpdpした際に、その表はどのSCNまで反映し終わっているか、というデータを内部的に付与してくれます。 環境の前提 add trandata preparecsn noneを指定した場合の動作になります。 none以外を設定した場合は下記の内容は異なる場合がありますのでご注意ください。 add trandata preparescn noneをした場合の動作 マニュアルに記載があるとおり、この場合はインスタンス化の準備は行われません。 ソース側でのエクスポート [oracle@xxxxxxxx1p ~]$ expdp ggtest/xxxxxx DIRECTORY=homedir DUMPFILE=t10.dmp TABLES=t10 CONTENT=DATA_ONLY REUSE_DUMPFILES=YES Export: Release 11.2.0.4.0 - Production on 日 3月 3 16:47:00 2019 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. 接続先: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP, Data Mining and Real Application Testing options FLASHBACKでは、データベース整合性が自動的に維持されます。 "GGTEST"."SYS_EXPORT_TABLE_01"を起動しています: ggtest DIRECTORY=homedir DUMPFILE=t10.dmp TABLES=t10 CONTENT=DATA_ONLY REUSE_DUMPFILES=YES BLOCKSメソッドを使用して見積り中です... オブジェクト型TABLE_EXPORT/TABLE/TABLE_DATAの処理中です BLOCKSメソッドを使用した見積り合計: 384 KB . . "GGTEST"."T10" 288.6 KB 10000行がエクスポートされました マスター表"GGTEST"."SYS_EXPORT_TABLE_01"は正常にロード/アンロードされました ****************************************************************************** GGTEST.SYS_EXPORT_TABLE_01に設定されたダンプ・ファイルは次のとおりです: /home/oracle/t10.dmp ジョブ"GGTEST"."SYS_EXPORT_TABLE_01"が日 3月 3 16:47:04 2019 elapsed 0 00:00:02で正常に完了しました ターゲット側のインポート [oracle@xxxxxx ~]$ impdp ggtest/xxxxxx@xxxxxxxx1 DIRECTORY=homedir DUMPFILE=t10.dmp tables=t10 Import: Release 18.0.0.0.0 - Production on 日 3月 3 16:48:33 2019 Version 18.4.0.0.0 Copyright (c) 1982, 2018, Oracle and/or its affiliates. All rights reserved. 接続先: Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production マスター表"GGTEST"."SYS_IMPORT_TABLE_01"は正常にロード/アンロードされました "GGTEST"."SYS_IMPORT_TABLE_01"を起動しています: ggtest@xxxxxxxx1 DIRECTORY=homedir DUMPFILE=t10.dmp tables=t10 オブジェクト型TABLE_EXPORT/TABLE/TABLE_DATAの処理中です . . "GGTEST"."T10" 288.6 KB 10000行がインポートされました ジョブ"GGTEST"."SYS_IMPORT_TABLE_01"が日 3月 3 16:48:45 2019 elapsed 0 00:00:09で正常に完了しました インスタンス化SCNの確認 preparescn noneのため、この場合はインスタンスSCN化されていません。 SQL> select source_database,source_object_owner,source_object_name,instantiation_scn from DBA_APPLY_INSTANTIATED_OBJECTS where SOURCE_OBJECT_NAME='T10'; 行が選択されていません expdp時にFLASHBACK_SCNを使用した場合 ここでようやく表題の件ですが、このケースはtrandata時にpreparecsn noneに設定した場合においてもインスタンス化SCNがexpdp時に設定される動作のようです。 エクスポート時のコマンド ここで特定時点のFLASHBACK_SCNを指定します。 [oracle@xxxxxxxx1p ~]$ expdp ggtest/xxxxxx DIRECTORY=homedir DUMPFILE=t10.dmp TABLES=t10 CONTENT=DATA_ONLY REUSE_DUMPFILES=YES FLASHBACK_SCN=25587768 Export: Release 11.2.0.4.0 - Production on 日 3月 3 16:59:04 2019 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. 接続先: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP, Data Mining and Real Application Testing options FLASHBACKでは、データベース整合性が自動的に維持されます。 "GGTEST"."SYS_EXPORT_TABLE_01"を起動しています: ggtest DIRECTORY=homedir DUMPFILE=t10.dmp TABLES=t10 CONTENT=DATA_ONLY REUSE_DUMPFILES=YES FLASHBACK_SCN=25587768 BLOCKSメソッドを使用して見積り中です... オブジェクト型TABLE_EXPORT/TABLE/TABLE_DATAの処理中です BLOCKSメソッドを使用した見積り合計: 384 KB . . "GGTEST"."T10" 288.6 KB 10000行がエクスポートされました マスター表"GGTEST"."SYS_EXPORT_TABLE_01"は正常にロード/アンロードされました ****************************************************************************** GGTEST.SYS_EXPORT_TABLE_01に設定されたダンプ・ファイルは次のとおりです: /home/oracle/t10.dmp ジョブ"GGTEST"."SYS_EXPORT_TABLE_01"が日 3月 3 16:59:08 2019 elapsed 0 00:00:02で正常に完了しました FLASHBACK_SCN を指定してexpdpしたdmpファイルをimpdpした場合、 DBA_APPLY_INSTANTIATED_OBJECTS は INSTANTIATION_SCNが設定されています。 SQL> select source_database,source_object_owner,source_object_name,instantiation_scn from DBA_APPLY_INSTANTIATED_OBJECTS where SOURCE_OBJECT_NAME='T10'; SOURCE_DATABASE SOURCE_OBJECT_OWNER SOURCE_OBJECT_NAME INSTANTIATION_SCN xxxxxxx GGTEST T10 25587768 ←★INSTANTIATION_SCNが設定されている まとめ add trandata時にpreparecsn noneを設定した場合においてもexpdp時にFLASHBACK_SCNを使用した場合はインスタンス化SCNが設定されるという動作になります。 この動作についてですが、streamsのマニュアルに記載があります。合わせてご確認ください。 https://docs.oracle.com/cd/E16338_01/server.112/b61352/instant.htm#CIHBDFJE エクスポート中、Oracle Data Pumpでは、データベース・オブジェクトごとにエクスポートされたデータおよび手続き型操作が特定の時点で一貫性を持つように、自動的にOracle Flashbackが使用されます。Oracle Streams環境でインスタンス化を実行する場合は、ある程度の一貫性が必要です。データ・ポンプ・エクスポート・ユーティリティを使用すると、Oracle Streamsのインスタンス化についてこの一貫性を確保できます。 Oracle Streamsのインスタンス化のみでなく、他の用途にもエクスポート・ダンプ・ファイルを使用しており、その用途がデータ・ポンプのデフォルトのエクスポートで得られる一貫性より厳密な一貫性要件を伴う場合は、Oracle Streamsのインスタンス化にデータ・ポンプ・エクスポート・ユーティリティ・パラメータFLASHBACK_SCNまたはFLASHBACK_TIMEを使用できます。たとえば、エクスポートに外部キー制約を持つオブジェクトが含まれている場合、より厳密な一貫性が要求される場合があります。 --- ### GoldenGateをインストールしてDB間のレプリケーション環境を構築する date: 2019-03-29 url: https://zatoima.github.io/goldengate-12c-18c-install-implement.html tags: Oracle, GoldenGate GoldenGateを使用してOracle Database間のレプリケーションを構築します。 レプリケーションまでのステップは下記の通りですが、本記事だと「1.」と「2.」を対象にしています。 GoldenGateインストール GoldenGate環境設定 データ伝搬 環境構成 マシンスペックの関係で同一マシン内に2DBを作成しています。この2DBをGoldenGateを使用してレプリケーション環境を作成します。 ソース ターゲット DBバージョン 11.2.0.4 18c GoldenGateバージョン 12.2.0.1 18.1.0.0.0 DB名 db112s db18s PDB名 - db18p1 GoldenGate用DBユーザ ggs c##ggs 伝搬用ユーザ ggtest ggtest GoldenGateインストール先 /gg/gg1 /gg/gg2 Captureプロセス c11 - Data Pumpプロセス d11 - Replicatプロセス - r11 Captureプロセスのモード 統合モード(Integrated Capture) - Replicatプロセスのモード - 統合モード(Integrated Replicat) その他 シングル構成 前提事項 既にソースDBとターゲットDBがインストールされていること GoldenGateのメディアファイルを事前にダウンロードしていること GoldenGateインストール GG_HOMEの作成 今回はCUIベースでのインストールを行います。GUIでインストールしたい場合は下記qiitaの記事をご参照ください。 GoldenGate布教活動② ~GoldenGateのインストール~ - Qiita https://qiita.com/ch0c0bana0/items/a57debf29a8d907e9feb su - mkdir -p /gg/gg1 mkdir -p /gg/gg2 chmod -R 755 /gg chown -R oracle:oinstall /gg exit GoldenGate12cR2(12.2.0.1)のインストール メディア・ファイルの解凍 #コマンド cd /home/oracle/software/goldengate/12.2.0.1/V100692-01 ls -l unzip V100692-01.zip #実行結果 [oracle@dbvgg V100692-01]$ [oracle@dbvgg V100692-01]$ cd /home/oracle/software/goldengate/12.2.0.1/V100692-01 [oracle@dbvgg V100692-01]$ ls -l 合計 464468 -rwxr-xr-x 1 oracle oinstall 475611228 7月 7 19:15 2017 V100692-01.zip [oracle@dbvgg V100692-01]$ unzip V100692-01.zip Archive: V100692-01.zip creating: fbo_ggs_Linux_x64_shiphome/ creating: fbo_ggs_Linux_x64_shiphome/Disk1/ ~中略~ creating: fbo_ggs_Linux_x64_shiphome/Disk1/response/ inflating: fbo_ggs_Linux_x64_shiphome/Disk1/response/oggcore.rsp inflating: OGG-12.2.0.1-README.txt inflating: OGG-12.2.0.1.1-ReleaseNotes.pdf [oracle@dbvgg V100692-01]$ サイレントインストール用のレスポンスファイルの修正 ★部分が修正箇所になります。環境に合わせて修正する必要があります。 cd ./fbo_ggs_Linux_x64_shiphome/Disk1/response ls -l vi oggcore.rsp #oggcore.rspの修正内容 #################################################################### ## Copyright(c) Oracle Corporation 2014. All rights reserved. ## ## ## ## Specify values for the variables listed below to customize ## ## your installation. ## ## ## ## Each variable is associated with a comment. The comment ## ## can help to populate the variables with the appropriate ## ## values. ## ## ## ## IMPORTANT NOTE: This file should be secured to have read ## ## permission only by the oracle user or an administrator who ## ## own this installation to protect any sensitive input values. ## ## ## #################################################################### #------------------------------------------------------------------------------- # Do not change the following system generated value. #------------------------------------------------------------------------------- oracle.install.responseFileVersion=/oracle/install/rspfmt_ogginstall_response_schema_v12_1_2 ################################################################################ ## ## ## Oracle GoldenGate installation option and details ## ## ## ################################################################################ #------------------------------------------------------------------------------- # Specify the installation option. # Specify ORA12c for installing Oracle GoldenGate for Oracle Database 12c and # ORA11g for installing Oracle GoldenGate for Oracle Database 11g #------------------------------------------------------------------------------- INSTALL_OPTION=ORA11g ★← #------------------------------------------------------------------------------- # Specify a location to install Oracle GoldenGate #------------------------------------------------------------------------------- SOFTWARE_LOCATION=/gg/gg1 ★← #------------------------------------------------------------------------------- # Specify true to start the manager after installation. #------------------------------------------------------------------------------- START_MANAGER=false ★← #------------------------------------------------------------------------------- # Specify a free port within the valid range for the manager process. # Required only if START_MANAGER is true. #------------------------------------------------------------------------------- MANAGER_PORT= #------------------------------------------------------------------------------- # Specify the location of the Oracle Database. # Required only if START_MANAGER is true. #------------------------------------------------------------------------------- DATABASE_LOCATION= ################################################################################ ## ## ## Specify details to Create inventory for Oracle installs ## ## Required only for the first Oracle product install on a system. ## ## ## ################################################################################ #------------------------------------------------------------------------------- # Specify the location which holds the install inventory files. # This is an optional parameter if installing on # Windows based Operating System. #------------------------------------------------------------------------------- INVENTORY_LOCATION= #------------------------------------------------------------------------------- # Unix group to be set for the inventory directory. # This parameter is not applicable if installing on # Windows based Operating System. #------------------------------------------------------------------------------- UNIX_GROUP_NAME= GoldenGateインストール cd /home/oracle/software/goldengate/12.2.0.1/V100692-01/fbo_ggs_Linux_x64_shiphome/Disk1 ./runInstaller -silent -nowait -responseFile /home/oracle/software/goldengate/12.2.0.1/V100692-01/fbo_ggs_Linux_x64_shiphome/Disk1/response/oggcore.rsp #実行結果 [oracle@dbvgg Disk1]$ ./runInstaller -silent -nowait -responseFile /home/oracle/software/goldengate/12.2.0.1/V100692-01/fbo_ggs_Linux_x64_shiphome/Disk1/response/oggcore.rsp Oracle Universal Installerを起動中です... 一時領域の確認中: 120MBを超えている必要があります. 実際 28028MB 問題なし スワップ領域の確認中: 150MBを超えている必要があります. 実際 7855MB 問題なし Oracle Universal Installerの起動を準備中 /tmp/OraInstall2019-03-29_05-24-01PM. お待ちください... このインストール・セッションのログは次の場所にあります: /u01/app/oraInventory/logs/installActions2019-03-29_05-24-01PM.log Oracle GoldenGate Coreのインストールが成功しました。 詳細は'/u01/app/oraInventory/logs/silentInstall2019-03-29_05-24-01PM.log'を確認してください。 Successfully Setup Software. [oracle@dbvgg Disk1]$ OPatch更新 #OPatch更新 cd /home/oracle/software/goldengate/12.2.0.1/p6880880 unzip p6880880_112000_Linux-x86-64.zip cp -Rp ./OPatch/* /gg/gg1/OPatch/ /gg/gg1/OPatch/opatch version #実行結果 [oracle@dbvgg p6880880]$ /gg/gg1/OPatch/opatch version OPatch Version: 11.2.0.3.19 OPatch succeeded. [oracle@dbvgg p6880880]$ GoldenGate用のPatch更新 #OPatch更新 export ORACLE_HOME=/gg/gg1 export PATH=$ORACLE_HOME/OPatch:$PATH cd /home/oracle/software/goldengate/12.2.0.1/p26849940 unzip p26849940_12201170919_Linux-x86-64.zip cd 26849940/ /gg/gg1/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -ph ./ $ORACLE_HOME/OPatch/opatch apply -oh $ORACLE_HOME $ORACLE_HOME/OPatch/opatch lspatches $ORACLE_HOME/OPatch/opatch lsinventory #実行結果 [oracle@dbvgg 26849940]$ $ORACLE_HOME/OPatch/opatch apply -oh $ORACLE_HOME Oracle Interim Patch Installerバージョン11.2.0.3.19 Copyright (c) 2019, Oracle Corporation. All rights reserved。 Oracle Home : /gg/gg1 Central Inventory : /u01/app/oraInventory from : /gg/gg1/oraInst.loc OPatch version : 11.2.0.3.19 OUI version : 11.2.0.3.0 Log file location : /gg/gg1/cfgtoollogs/opatch/opatch2019-03-29_17-36-23午後_1.log Verifying environment and performing prerequisite checks... OPatch continues with these patches: 26849940 続行しますか。[y|n] y User Responded with: Y All checks passed. セキュリティの問題について通知を受ける電子メール・アドレスを指定し、Oracle Configuration Managerをインストールして開始してください。My Oracle Supportの電子メール・アドレス/ユーザー名を使用すればより簡単です。 詳細はhttp://www.oracle.com/support/policies.htmlにアクセスしてください。 電子メール・アドレス/ユーザー名: セキュリティの問題について通知を受け取るための電子メール・アドレスが指定されていません。 セキュリティの問題に関する通知を今後も受け取りませんか([Y]はい, [N]いいえ) [N]: y ローカル・システムのこのORACLE_HOME以外で実行しているOracleインスタンスを停止してください。 (Oracleホーム = '/gg/gg1') ローカル・システムにパッチを適用する準備ができましたか。 [y|n] y User Responded with: Y Backing up files... Applying interim patch '26849940' to OH '/gg/gg1' コンポーネントoracle.oggcore.ora11g, 12.2.0.0.0にパッチを適用中... Patch 26849940 successfully applied. Log file location: /gg/gg1/cfgtoollogs/opatch/opatch2019-03-29_17-36-23午後_1.log OPatch succeeded. [oracle@dbvgg 26849940]$ [oracle@dbvgg 26849940]$ $ORACLE_HOME/OPatch/opatch lspatches 26849940; OPatch succeeded. [oracle@dbvgg 26849940]$ [oracle@dbvgg 26849940]$ $ORACLE_HOME/OPatch/opatch lsinventory Oracle Interim Patch Installerバージョン11.2.0.3.19 Copyright (c) 2019, Oracle Corporation. All rights reserved。 Oracle Home : /gg/gg1 Central Inventory : /u01/app/oraInventory from : /gg/gg1/oraInst.loc OPatch version : 11.2.0.3.19 OUI version : 11.2.0.3.0 Log file location : /gg/gg1/cfgtoollogs/opatch/opatch2019-03-29_17-38-37午後_1.log Lsinventory Output file location : /gg/gg1/cfgtoollogs/opatch/lsinv/lsinventory2019-03-29_17-38-37午後.txt -------------------------------------------------------------------------------- Local Machine Information:: Hostname: dbvgg.jp.oracle.com ARU platform id: 226 ARU platform description:: Linux x86-64 インストールされた最上位製品(1): Oracle GoldenGate Core 12.2.0.0.0 このOracleホームには1の製品がインストールされています。 仮パッチ(1) : Patch 26849940 : applied on Fri Mar 29 17:37:09 JST 2019 Unique Patch ID: 21947835 Created on 13 Feb 2018, 15:29:18 hrs PST8PDT Bugs fixed: 26112114, 21254311, 22628312, 25256300, 24339776, 22466155, 21562399 22910007, 22642576, 25096792, 25252388, 26122243, 25031466, 24826961 24804392, 22912874, 24312736, 24302758, 24414523, 23733399, 22959377 23514258, 25369310, 21548970, 23642240, 22266611, 23058710, 24744349 25918872, 24598011, 25797611, 23755469, 25667779, 21131090, 22202129 22478792, 25814949, 22830589, 22295723, 22993705, 25213169, 23102612 22458470, 23750747, 21888279, 23267559, 22295940, 22730188, 25674499 23712604, 25137084, 25350730, 22811754, 26127417, 20822775, 24439762 23661056, 23607346, 23641740, 23499047, 22352402, 23751229, 25439681 24345528, 22514172, 25927416, 25463128, 23478103, 23587474, 23763062 21425179, 23067041, 24359320, 22046726, 21763449, 23479013, 23275654 25231249, 23133585, 22004485, 23608765, 25087704, 26000622, 24752349 23108041, 22455149, 25462009, 26253307, 22103949, 24310901, 21452073 23580290, 25414758, 23040154, 22257964, 26159982, 22888353, 24751551 21805148, 21481506, 22553129, 23328064, 20656312 -------------------------------------------------------------------------------- OPatch succeeded. [oracle@dbvgg 26849940]$ GoldenGate18c(18.1.0.0.0)のインストール メディア・ファイルの解凍 #コマンド cd /home/oracle/software/goldengate/18.1.0.0/V980002-01 ls -l unzip V980002-01.zip #実行結果 [oracle@dbvgg V980002-01]$ cd /home/oracle/software/goldengate/18.1.0.0/V980002-01 [oracle@dbvgg V980002-01]$ [oracle@dbvgg V980002-01]$ ll 合計 383516 -rwxr-xr-x 1 oracle oinstall 392717701 10月 19 11:16 2018 V980002-01.zip [oracle@dbvgg V980002-01]$ [oracle@dbvgg V980002-01]$ [oracle@dbvgg V980002-01]$ unzip V980002-01.zip Archive: V980002-01.zip creating: fbo_ggs_Linux_x64_shiphome/ ~中略~ inflating: fbo_ggs_Linux_x64_shiphome/Disk1/stage/sizes/oracle.oggcore.top18.1.0.0.0ora18c.sizes.properties inflating: OGG-18.1.0.0-README.txt inflating: OGG_WinUnix_Rel_Notes_18.1.0.0.0.pdf [oracle@dbvgg V980002-01]$ サイレントインストール用のレスポンスファイルの修正 ★部分が修正箇所になります。環境に合わせて修正する必要があります。 cd ./fbo_ggs_Linux_x64_shiphome/Disk1/response ls -l vi oggcore.rsp #oggcore.rspの修正内容 #################################################################### ## Copyright(c) Oracle Corporation 2018. All rights reserved. ## ## ## ## Specify values for the variables listed below to customize ## ## your installation. ## ## ## ## Each variable is associated with a comment. The comment ## ## can help to populate the variables with the appropriate ## ## values. ## ## ## ## IMPORTANT NOTE: This file should be secured to have read ## ## permission only by the oracle user or an administrator who ## ## own this installation to protect any sensitive input values. ## ## ## #################################################################### #------------------------------------------------------------------------------- # Do not change the following system generated value. #------------------------------------------------------------------------------- oracle.install.responseFileVersion=/oracle/install/rspfmt_ogginstall_response_schema_v12_1_2 ################################################################################ ## ## ## Oracle GoldenGate installation option and details ## ## ## ################################################################################ #------------------------------------------------------------------------------- # Specify the installation option. # Specify ORA18c for installing Oracle GoldenGate for Oracle Database 18c or # ORA12c for installing Oracle GoldenGate for Oracle Database 12c or # ORA11g for installing Oracle GoldenGate for Oracle Database 11g #------------------------------------------------------------------------------- INSTALL_OPTION=ORA18c ★← #------------------------------------------------------------------------------- # Specify a location to install Oracle GoldenGate #------------------------------------------------------------------------------- SOFTWARE_LOCATION=/gg/gg2 ★← #------------------------------------------------------------------------------- # Specify true to start the manager after installation. #------------------------------------------------------------------------------- START_MANAGER=false ★← #------------------------------------------------------------------------------- # Specify a free port within the valid range for the manager process. # Required only if START_MANAGER is true. #------------------------------------------------------------------------------- MANAGER_PORT= #------------------------------------------------------------------------------- # Specify the location of the Oracle Database. # Required only if START_MANAGER is true. #------------------------------------------------------------------------------- DATABASE_LOCATION= ################################################################################ ## ## ## Specify details to Create inventory for Oracle installs ## ## Required only for the first Oracle product install on a system. ## ## ## ################################################################################ #------------------------------------------------------------------------------- # Specify the location which holds the install inventory files. # This is an optional parameter if installing on # Windows based Operating System. #------------------------------------------------------------------------------- INVENTORY_LOCATION= #------------------------------------------------------------------------------- # Unix group to be set for the inventory directory. # This parameter is not applicable if installing on # Windows based Operating System. #------------------------------------------------------------------------------- UNIX_GROUP_NAME= GoldenGateインストール cd /home/oracle/software/goldengate/18.1.0.0/V980002-01/fbo_ggs_Linux_x64_shiphome/Disk1 ./runInstaller -silent -nowait -responseFile /home/oracle/software/goldengate/18.1.0.0/V980002-01/fbo_ggs_Linux_x64_shiphome/Disk1/response/oggcore.rsp #実行結果 [oracle@dbvgg Disk1]$ ./runInstaller -silent -nowait -responseFile /home/oracle/software/goldengate/18.1.0.0/V980002-01/fbo_ggs_Linux_x64_shiphome/Disk1/response/oggcore.rsp Oracle Universal Installerを起動中です... 一時領域の確認中: 120MBを超えている必要があります. 実際 25219MB 問題なし スワップ領域の確認中: 150MBを超えている必要があります. 実際 7855MB 問題なし Oracle Universal Installerの起動を準備中 /tmp/OraInstall2019-03-29_05-44-14PM. お待ちください... このインストール・セッションのログは次の場所にあります: /u01/app/oraInventory/logs/installActions2019-03-29_05-44-14PM.log Oracle GoldenGate Coreのインストールが成功しました。 詳細は'/u01/app/oraInventory/logs/silentInstall2019-03-29_05-44-14PM.log'を確認してください。 Successfully Setup Software. [oracle@dbvgg Disk1]$ Trailファイル格納ディレクトリの作成 「/gg/gg1/c11」はソース側のCaptureプロセスが生成するLocal Trailの格納ディレクトリ、「/gg/gg2/d11」はData Pumpがターゲット側に生成するRemote Trailの格納ディレクトリとなります。 mkdir -p /gg/gg1/dirdat/c11 #Local Trail用の格納ディレクトリ mkdir -p /gg/gg2/dirdat/d11 #Remote Trail用の格納ディレクトリ DB環境変更(ソース側) 表領域の作成 . /home/oracle/.oraenv_db112s --環境変数の読み込み sqlplus / as sysdba create tablespace ggdata datafile '/u01/app/oracle/oradata/DB112S/datafile/ggdata.dbf' size 5G; 伝搬対象ユーザ、及びGoldenGate管理ユーザの作成 CREATE USER ggs IDENTIFIED BY oracle DEFAULT TABLESPACE ggdata; CREATE USER ggtest IDENTIFIED BY oracle DEFAULT TABLESPACE ggdata; GRANT dba TO ggs; GRANT dba TO ggtest; exec dbms_goldengate_auth.grant_admin_privilege('GGS'); 初期化パラメータの変更/最小サプリメンタルロギングの設定 -- 事前確認 show parameter enable_goldengate_replication select name,supplemental_log_data_min from v$database; select log_mode from v$database; -- 初期化パラメータの変更 alter system set enable_goldengate_replication=true scope=both; alter system set streams_pool_size=1250M scope=both SID='*'; -- Integrated Capture要件 -- 最小サプリメンタルロギングの設定 alter database add supplemental log data; alter system switch logfile; -- 設定変更確認 show parameter enable_goldengate_replication select name,supplemental_log_data_min from v$database; select log_mode from v$database; exit -- 実行結果 SQL> show parameter enable_goldengate_replication NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ enable_goldengate_replication boolean FALSE SQL> SQL> select name,supplemental_log_data_min from v$database; NAME SUPPLEME --------- -------- DB112S NO SQL> select log_mode from v$database; LOG_MODE ------------ ARCHIVELOG SQL> SQL> SQL> alter system set enable_goldengate_replication=true scope=both; システムが変更されました。 SQL> alter system set streams_pool_size=1250M scope=both SID='*'; システムが変更されました。 SQL> alter database add supplemental log data; データベースが変更されました。 SQL> alter system switch logfile; システムが変更されました。 SQL> show parameter enable_goldengate_replication NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ enable_goldengate_replication boolean TRUE SQL> select name,supplemental_log_data_min from v$database; NAME SUPPLEME --------- -------- DB112S YES SQL> select log_mode from v$database; LOG_MODE ------------ ARCHIVELOG SQL> DB環境変更(ターゲット側) 表領域の作成 . /home/oracle/.oraenv_db18s --環境変数の読み込み sqlplus / as sysdba create tablespace ggdata datafile '/u01/app/oracle/oradata/DB18S/ggdata.dbf' size 1G; alter session set container=db18p1; create tablespace ggdata datafile '/u01/app/oracle/oradata/DB18S/db18p1/ggdata.dbf' size 5G; 伝搬対象ユーザ、及びGoldenGate管理ユーザの作成 alter session set container=cdb$root; show con_name CREATE USER c##ggs IDENTIFIED BY oracle DEFAULT TABLESPACE ggdata; alter session set container=db18p1; show con_name CREATE USER ggtest IDENTIFIED BY oracle DEFAULT TABLESPACE ggdata; alter session set container=cdb$root; GRANT DBA TO c##ggs container=all; exec dbms_goldengate_auth.grant_admin_privilege('C##GGS'); alter session set container=db18p1; GRANT DBA TO ggtest; exec dbms_goldengate_auth.grant_admin_privilege('C##GGS'); 初期化パラメータの変更/最小サプリメンタルロギングの設定 alter session set container=cdb$root; show con_name -- 事前確認 show parameter enable_goldengate_replication select name,supplemental_log_data_min from v$database; select log_mode from v$database; -- 初期化パラメータの変更 alter system set enable_goldengate_replication=true scope=both; alter system set streams_pool_size=1250M scope=both SID='*'; -- Integrated Replicat要件 -- 最小サプリメンタルロギングの設定 alter database add supplemental log data; -- ターゲット側なので本来であれば不要。logminer要件のため設定 alter system switch logfile; -- 設定変更確認 show parameter enable_goldengate_replication select name,supplemental_log_data_min from v$database; select log_mode from v$database; -- 実行結果 SQL> alter session set container=cdb$root; セッションが変更されました。 SQL> SQL> show con_name CON_NAME ------------------------------ CDB$ROOT SQL> show parameter enable_goldengate_replication NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ enable_goldengate_replication boolean FALSE SQL> select name,supplemental_log_data_min from v$database; NAME SUPPLEME --------- -------- DB18S NO SQL> select log_mode from v$database; LOG_MODE ------------ ARCHIVELOG SQL> alter system set enable_goldengate_replication=true scope=both; システムが変更されました。 SQL> alter system set streams_pool_size=1250M scope=both SID='*'; システムが変更されました。 SQL> alter database add supplemental log data; データベースが変更されました。 SQL> alter system switch logfile; システムが変更されました。 SQL> show parameter enable_goldengate_replication NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ enable_goldengate_replication boolean TRUE SQL> select name,supplemental_log_data_min from v$database; NAME SUPPLEME --------- -------- DB18S YES SQL> select log_mode from v$database; LOG_MODE ------------ ARCHIVELOG SQL> GoldenGate環境設定 GG_HOME配下のサブディレクトリ作成 サプリメンタル・ロギングはソース側で実施します。 . /home/oracle/.oraenv_db112s --環境変数の読み込み cd /gg/gg1 ./ggsci create subdirs exit cd /gg/gg2 ./ggsci create subdirs exit # 実行結果 [oracle@dbvgg gg1]$ ./ggsci Oracle GoldenGate Command Interpreter for Oracle Version 12.2.0.1.170919 OGGCORE_12.2.0.1.0OGGBP_PLATFORMS_171030.0908_FBO Linux, x64, 64bit (optimized), Oracle 11g on Oct 30 2017 19:19:45 Operating system character set identified as UTF-8. Copyright (C) 1995, 2017, Oracle and/or its affiliates. All rights reserved. GGSCI (dbvgg.jp.oracle.com) 1> create subdirs Creating subdirectories under current directory /gg/gg1 Parameter files /gg/gg1/dirprm: created Report files /gg/gg1/dirrpt: created Checkpoint files /gg/gg1/dirchk: created Process status files /gg/gg1/dirpcs: created SQL script files /gg/gg1/dirsql: created Database definitions files /gg/gg1/dirdef: created Extract data files /gg/gg1/dirdat: created Temporary files /gg/gg1/dirtmp: created Credential store files /gg/gg1/dircrd: created Masterkey wallet files /gg/gg1/dirwlt: created Dump files /gg/gg1/dirdmp: created GGSCI (dbvgg.jp.oracle.com) 2> GGSCI (dbvgg.jp.oracle.com) 3> exit [oracle@dbvgg gg1]$ cd /gg/gg2 [oracle@dbvgg gg2]$ ./ggsci Oracle GoldenGate Command Interpreter for Oracle Version 18.1.0.0.0 OGGCORE_18.1.0.0.0_PLATFORMS_180928.0432_FBO Linux, x64, 64bit (optimized), Oracle 18c on Sep 29 2018 07:21:38 Operating system character set identified as UTF-8. Copyright (C) 1995, 2018, Oracle and/or its affiliates. All rights reserved. GGSCI (dbvgg.jp.oracle.com) 1> create subdirs Creating subdirectories under current directory /gg/gg2 Parameter file /gg/gg2/dirprm: created. Report file /gg/gg2/dirrpt: created. Checkpoint file /gg/gg2/dirchk: created. Process status files /gg/gg2/dirpcs: created. SQL script files /gg/gg2/dirsql: created. Database definitions files /gg/gg2/dirdef: created. Extract data files /gg/gg2/dirdat: created. Temporary files /gg/gg2/dirtmp: created. Credential store files /gg/gg2/dircrd: created. Masterkey wallet files /gg/gg2/dirwlt: created. Dump files /gg/gg2/dirdmp: created. GGSCI (dbvgg.jp.oracle.com) 2> exit [oracle@dbvgg gg2]$ スキーマ・レベルのサプリメンタルロギングの実施 サプリメンタル・ロギングはソース側で実施します。 . /home/oracle/.oraenv_db112s --環境変数の読み込み cd /gg/gg1 ./ggsci dblogin userid ggs@db112s, password oracle add schematrandata ggtest # 実行結果 [oracle@dbvgg gg1]$ ./ggsci Oracle GoldenGate Command Interpreter for Oracle Version 12.2.0.1.170919 OGGCORE_12.2.0.1.0OGGBP_PLATFORMS_171030.0908_FBO Linux, x64, 64bit (optimized), Oracle 11g on Oct 30 2017 19:19:45 Operating system character set identified as UTF-8. Copyright (C) 1995, 2017, Oracle and/or its affiliates. All rights reserved. GGSCI (dbvgg.jp.oracle.com) 1> dblogin userid ggs@db112s, password oracle Successfully logged into database. GGSCI (dbvgg.jp.oracle.com as ggs@db112s) 2> add schematrandata ggtest 2019-03-29 17:59:55 INFO OGG-01788 SCHEMATRANDATA has been added on schema ggtest. 2019-03-29 17:59:55 INFO OGG-01976 SCHEMATRANDATA for scheduling columns has been added on schema ggtest. GGSCI (dbvgg.jp.oracle.com as ggs@db112s) 3> GGパラメータファイルの作成 GoldenGateのパラメータは各プロセスごとに作成する必要があります。GLOBALS、MGRパラメータはソース、及びターゲット側に存在するので両サイトで作成する必要があります。 GLOBALSパラメータ(ソース側) . /home/oracle/.oraenv_db112s --環境変数の読み込み cd /gg/gg1 ./ggsci EDIT PARAMS GLOBALS #下記をviエディタで指定する SYSLOG NONE GGSCHEMA ggs NODUPMSGSUPPRESSION view params GLOBALS MGRパラメータ(ソース側) . /home/oracle/.oraenv_db112s --環境変数の読み込み cd /gg/gg1 ./ggsci EDIT PARAMS MGR # MGRファイルの設定 PORT 7809 AUTOSTART EXTRACT c11 AUTOSTART EXTRACT d11 AUTORESTART EXTRACT c11, RETRIES 2, WAITMINUTES 1, RESETMINUTES 60 AUTORESTART EXTRACT d11, RETRIES 5, WAITMINUTES 1, RESETMINUTES 60 -- Trailファイルのメンテンス設定 PURGEOLDEXTRACTS ./dirdat/c11/*, USECHECKPOINTS, MINKEEPDAYS 1 view params GLOBALS Captureパラメータ(ソース側) . /home/oracle/.oraenv_db112s --環境変数の読み込み cd /gg/gg1 ./ggsci EDIT PARAMS C11 # CAPTUREファイルの設定 EXTRACT c11 USERID ggs@db112s,PASSWORD oracle EXTTRAIL ./dirdat/c11/lt CACHEMGR CACHESIZE 4GB DISCARDFILE ./dirrpt/c11.dsc, APPEND, MEGABYTES 500 DISCARDROLLOVER AT 2:00 ON SUNDAY REPORTROLLOVER AT 2:00 ON SUNDAY DDL INCLUDE ALL DDLOPTIONS CAPTUREGLOBALTEMPTABLE,REPORT TRANLOGOPTIONS INTEGRATEDPARAMS (MAX_SGA_SIZE 1250, PARALLELISM 2) TABLE ggtest.* ; view params MGR Data Pumpパラメータ(ソース側) 今回は筐体内の2DB間のレプリケーション設定なので、RMTHOSTに「localhost」を設定しています。本来ならばターゲットサーバのhostname、もしくはIPアドレスの指定が必要です。 . /home/oracle/.oraenv_db112s --環境変数の読み込み cd /gg/gg1 ./ggsci EDIT PARAMS d11 # Data Pumpファイルの設定 EXTRACT d11 PASSTHRU RMTHOST localhost, MGRPORT 7810 RMTTRAIL ./dirdat/d11/rt TABLE ggtest.*; view params c11 GLOBALSパラメータ(ターゲット側) . /home/oracle/.oraenv_db18s --環境変数の読み込み cd /gg/gg2 ./ggsci EDIT PARAM GLOBALS GGSCHEMA c##ggs NODUPMSGSUPPRESSION view params GLOBALS MGRパラメータ(ソース側) . /home/oracle/.oraenv_db112s --環境変数の読み込み cd /gg/gg2 ./ggsci EDIT PARAMS MGR # MGRファイルの設定 PORT 7810 AUTOSTART REPLICAT r11 AUTORESTART REPLICAT r11, RETRIES 2, WAITMINUTES 1, RESETMINUTES 60 -- Trailファイルのメンテンス設定 PURGEOLDEXTRACTS ./dirdat/d11/*, USECHECKPOINTS, MINKEEPDAYS 1 Replicatパラメータ(ターゲット側) . /home/oracle/.oraenv_db112s --環境変数の読み込み cd /gg/gg2 ./ggsci EDIT PARAMS R11 REPLICAT r11 USERID c##ggs@db18p1, PASSWORD oracle DBOPTIONS INTEGRATEDPARAMS(PARALLELISM 4,MAX_PARALLELISM 4) DISCARDFILE ./dirrpt/r11.dsc, APPEND, MEGABYTES 500 DISCARDROLLOVER AT 2:00 ON SUNDAY REPORTROLLOVER AT 2:00 ON SUNDAY DDL INCLUDE ALL DDLOPTIONS CAPTUREGLOBALTEMPTABLE,REPORT REPORTCOUNT EVERY 10 MINUTES, RATE BATCHSQL MAP ggtest.* ,TARGET db18p1.ggtest.*; GoldenGateプロセス作成 ソース側のプロセス作成 . /home/oracle/.oraenv_db112s --環境変数の読み込み cd /gg/gg1 ./ggsci #DBログイン dblogin userid ggs@db112s,password oracle #Captuteプロセスの作成・追加 REGISTER EXTRACT c11 DATABASE add extract c11, integrated,tranlog, begin now add exttrail ./dirdat/c11/lt, extract c11, megabytes 500 #Data Pumpプロセスの作成・追加 add extract d11, exttrailsource ./dirdat/c11/lt add rmttrail ./dirdat/d11/rt, extract d11 #確認 info all # 実行結果 GGSCI (dbvgg.jp.oracle.com) 1> dblogin userid ggs@db112s,password oracle Successfully logged into database. GGSCI (dbvgg.jp.oracle.com as ggs@db112s) 2> REGISTER EXTRACT c11 DATABASE 2019-03-29 18:18:00 INFO OGG-02003 Extract C11 successfully registered with database at SCN 1089847. GGSCI (dbvgg.jp.oracle.com as ggs@db112s) 3> add extract c11, integrated,tranlog, begin now EXTRACT (Integrated) added. GGSCI (dbvgg.jp.oracle.com as ggs@db112s) 4> add exttrail ./dirdat/c11/lt, extract c11, megabytes 500 EXTTRAIL added. GGSCI (dbvgg.jp.oracle.com as ggs@db112s) 5> GGSCI (dbvgg.jp.oracle.com as ggs@db112s) 5> GGSCI (dbvgg.jp.oracle.com as ggs@db112s) 5> add extract d11, exttrailsource ./dirdat/c11/lt EXTRACT added. GGSCI (dbvgg.jp.oracle.com as ggs@db112s) 6> GGSCI (dbvgg.jp.oracle.com as ggs@db112s) 6> add rmttrail ./dirdat/d11/rt, extract d11 RMTTRAIL added. GGSCI (dbvgg.jp.oracle.com as ggs@db112s) 7> GGSCI (dbvgg.jp.oracle.com as ggs@db112s) 7> info all Program Status Group Lag at Chkpt Time Since Chkpt MANAGER STOPPED EXTRACT STOPPED C11 00:00:00 00:00:17 EXTRACT STOPPED D11 00:00:00 00:00:07 GGSCI (dbvgg.jp.oracle.com as ggs@db112s) 8> ターゲット側のプロセス作成 ReplicatはPDBに対して適用するため、dblogin時に指定する接続記述子はCDB$ROOTではなく適用するPDBへの指定が必要です。 またIntegrated Catptureの場合はregisterコマンドが必要でしたが、Integrated Replicatの場合は不要です。(内部的に発行されています。) . /home/oracle/.oraenv_db18s --環境変数の読み込み cd /gg/gg2 ./ggsci #DBログイン dblogin userid c##ggs@db18p1,password oracle #Replicatプロセスの作成 ADD REPLICAT r11,integrated EXTTRAIL ./dirdat/d11/rt #状態確認 info all # 実行結果 GGSCI (dbvgg.jp.oracle.com) 1> dblogin userid c##ggs@db18p1,password oracle Successfully logged into database DB18P1. GGSCI (dbvgg.jp.oracle.com as c##ggs@db18s/DB18P1) 2> GGSCI (dbvgg.jp.oracle.com as c##ggs@db18s/DB18P1) 2> ADD REPLICAT r11,integrated EXTTRAIL ./dirdat/d11/rt REPLICAT (Integrated) added. GGSCI (dbvgg.jp.oracle.com as c##ggs@db18s/DB18P1) 3> GGSCI (dbvgg.jp.oracle.com as c##ggs@db18s/DB18P1) 3> info all Program Status Group Lag at Chkpt Time Since Chkpt MANAGER STOPPED REPLICAT STOPPED R11 00:00:00 00:00:20 GGSCI (dbvgg.jp.oracle.com as c##ggs@db18s/DB18P1) 4> GoldenGateプロセス起動 ソース側のData Pumpプロセスはターゲット側のMGRプロセスと通信をします。したがって、先にターゲット側のMGRプロセスを起動する必要があるため、ターゲット側から起動を行います。 ターゲット側のプロセス起動 . /home/oracle/.oraenv_db18s --環境変数の読み込み cd /gg/gg1 ./ggsci #起動コマンド start mgr # mgrのパラメータでautostartを設定しているためreplicatプロセスの起動は不要。 #start r11 #状態確認コマンド info all # 実行結果 [oracle@dbvgg gg2]$ ./ggsci Oracle GoldenGate Command Interpreter for Oracle Version 18.1.0.0.0 OGGCORE_18.1.0.0.0_PLATFORMS_180928.0432_FBO Linux, x64, 64bit (optimized), Oracle 18c on Sep 29 2018 07:21:38 Operating system character set identified as UTF-8. Copyright (C) 1995, 2018, Oracle and/or its affiliates. All rights reserved. GGSCI (dbvgg.jp.oracle.com) 1> info all Program Status Group Lag at Chkpt Time Since Chkpt MANAGER STOPPED REPLICAT STOPPED R11 00:00:00 00:00:49 GGSCI (dbvgg.jp.oracle.com) 2> start mgr Manager started. GGSCI (dbvgg.jp.oracle.com) 3> info all Program Status Group Lag at Chkpt Time Since Chkpt MANAGER RUNNING REPLICAT RUNNING R11 00:00:00 00:00:03 GGSCI (dbvgg.jp.oracle.com) 4> ソース側のプロセス起動 . /home/oracle/.oraenv_db112s --環境変数の読み込み cd /gg/gg1 ./ggsci #起動コマンド start mgr # mgrのパラメータでautostartを設定しているためcapture、data pumpプロセスの起動は不要。 # start c11 # start d11 #状態確認コマンド info all # 実行結果 [oracle@dbvgg gg1]$ ./ggsci Oracle GoldenGate Command Interpreter for Oracle Version 12.2.0.1.170919 OGGCORE_12.2.0.1.0OGGBP_PLATFORMS_171030.0908_FBO Linux, x64, 64bit (optimized), Oracle 11g on Oct 30 2017 19:19:45 Operating system character set identified as UTF-8. Copyright (C) 1995, 2017, Oracle and/or its affiliates. All rights reserved. GGSCI (dbvgg.jp.oracle.com) 1> info all Program Status Group Lag at Chkpt Time Since Chkpt MANAGER STOPPED EXTRACT STOPPED C11 00:00:02 00:00:30 EXTRACT STOPPED D11 00:00:00 00:00:29 GGSCI (dbvgg.jp.oracle.com) 2> start mgr Manager started. GGSCI (dbvgg.jp.oracle.com) 3> info all Program Status Group Lag at Chkpt Time Since Chkpt MANAGER RUNNING EXTRACT RUNNING C11 00:00:10 00:00:07 EXTRACT RUNNING D11 00:00:00 00:00:04 GGSCI (dbvgg.jp.oracle.com) 4> Appendix OGG-02912エラー対応 **DB11.2とGG12.2(Integrated Capture)**の組み合わせで初回起動時、OGG-02912が発生し Capture プロセスが ABENDする場合があります。(適用されているPSU/BPに依存します。) Oracle GoldenGate12.2 からTrailファイルのフォーマットが変更されていることによるエラーです。(データベース側のログマイナーに関するファンクションが対応していない場合に発生します。) ERROR OGG-02912 Patch 17030189 is required on your Oracle mining database for trail format RELEASE 12.2 or later. エラーが発生した場合はエラーメッセージにある通り「Patch 17030189」を適用するか、GG_HOME配下にある「prvtlmpg.plb」を実行することでエラーを回避することが出来ます。 . /home/oracle/.oraenv_db112s --環境変数の読み込み cd /gg/gg1 sqlplus / as sysdba @prvtlmpg.plb -- 実行結果 [oracle@dbvgg gg1]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.4.0 Production on 金 3月 29 18:22:29 2019 Copyright (c) 1982, 2013, Oracle. All rights reserved. Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options に接続されました。 SQL> @prvtlmpg.plb Oracle GoldenGate Workaround prvtlmpg This script provides a temporary workaround for bug 17030189. It is strongly recommended that you apply the official Oracle Patch for bug 17030189 from My Oracle Support instead of using this workaround. This script must be executed in the mining database of Integrated Capture. You will be prompted for the username of the mining user. Use a double quoted identifier if the username is case sensitive or contains special characters. In a CDB environment, this script must be executed from the CDB$ROOT container and the mining user must be a common user. =========================== WARNING ========================== You MUST stop all Integrated Captures that belong to this mining user before proceeding! ================================================================ Enter Integrated Capture mining user: ggs Installing workaround... エラーはありません。 エラーはありません。 エラーはありません。 Installation completed. SQL> SQL> Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing optionsとの接続が切断されました。 [oracle@dbvgg gg1]$ --- ### MERGE文のGoldenGateによる伝搬 date: 2019-03-10 url: https://zatoima.github.io/goldengate-merge-replication.html tags: Oracle, GoldenGate はじめに MERGE文による更新をソース側DBで実施した場合、GoldenGateでどのように実行されるかを確認。 当初の推察通りだったが、REDOログ・ファイルから更新情報を読み込むアーキテクチャ上、MERGE文でINSERTが使用された場合は、INSERT文をキャプチャするし、UPDATE文だった場合は当然UPDATE文で伝搬される。 テストデータ作成 drop table t1; create table t1(a number primary key,b number,c varchar(30),d number); insert into t1 values (1,dbms_flashback.get_system_change_number,'test',TO_NUMBER(TO_CHAR(SYSTIMESTAMP, 'YYYYMMDDHH24MISS'))); commit; drop table t2; create table t2(a number primary key,b number,c varchar(30),d number); insert into t2 values (1,dbms_flashback.get_system_change_number,'test',TO_NUMBER(TO_CHAR(SYSTIMESTAMP, 'YYYYMMDDHH24MISS'))); insert into t2 values (2,dbms_flashback.get_system_change_number,'test',TO_NUMBER(TO_CHAR(SYSTIMESTAMP, 'YYYYMMDDHH24MISS'))); insert into t2 values (3,dbms_flashback.get_system_change_number,'test',TO_NUMBER(TO_CHAR(SYSTIMESTAMP, 'YYYYMMDDHH24MISS'))); insert into t2 values (4,dbms_flashback.get_system_change_number,'test',TO_NUMBER(TO_CHAR(SYSTIMESTAMP, 'YYYYMMDDHH24MISS'))); commit; テストデータの確認 SQL> select * from t1; A B C D 1 1202613 test 20190610133851 SQL> select * from t2; A B C D 1 1202715 test 20190610133852 2 1202726 test 20190610133852 3 1202726 test 20190610133852 4 1202726 test 20190610133852 MERGE文の実行 MERGE INTO t1 USING t2 ON (t1.a = t2.a) WHEN MATCHED THEN UPDATE SET t1.b = t2.b WHEN NOT MATCHED THEN INSERT (a, b, c, d) VALUES (t2.a,t2.b,t2.c,t2.d) / MERGE後のテストデータ確認 SQL> select * from t1; A B C D 1 1202715 test 20190610133851 2 1202726 test 20190610133852 3 1202726 test 20190610133852 4 1202726 test 20190610133852 SQL> select * from t2; A B C D 1 1202715 test 20190610133852 2 1202726 test 20190610133852 3 1202726 test 20190610133852 4 1202726 test 20190610133852 GoldenGateの伝搬結果 A B C D --------------- --------------- ------------------------------ --------------- 1 1202715 test 20190610133851 2 1202726 test 20190610133852 3 1202726 test 20190610133852 4 1202726 test 20190610133852 SQL> A B C D --------------- --------------- ------------------------------ --------------- 1 1202715 test 20190610133852 2 1202726 test 20190610133852 3 1202726 test 20190610133852 4 1202726 test 20190610133852 ターゲット側の共有プール(v$sql)から実行されたSQLを確認 SELECT sql_id, plan_hash_value, sql_text, module, fetches, command_type, executions, first_load_time, last_active_time, action, service, is_bind_aware FROM V$SQL WHERE module='GoldenGate' and action like '%Apply Server'; 実行結果 少し見にくいが、INSERT文とUPDATE文がGGTESTスキーマのT1テーブルに実行されていることがわかる。 SQL> SELECT sql_id, 2 plan_hash_value, 3 sql_text, 4 module, 5 fetches, 6 command_type, 7 executions, 8 first_load_time, 9 last_active_time, 10 action, 11 service, 12 is_bind_aware 13 FROM V$SQL 14 WHERE module='GoldenGate' 15 and action like '%Apply Server'; "SQL_ID","PLAN_HASH_VALUE","SQL_TEXT","MODULE","FETCHES","COMMAND_TYPE","EXECUTIONS","FIRST_LOAD_TIME","LAST_ACTIVE_TIME","ACTION","SERVICE","IS_BIND_AWARE" "6j3z4vh2pudfs",0," INSERT /*+ restrict_all_ref_cons */ INTO ""GGTEST"".""T1"" (""A"",""B"",""C"",""D"") VALUES (:1 ,:2 ,:3 ,:4 )","GoldenGate",0,2,2,"2019-06-10/12:25:03",19-06-10,"OGG$R11 - Apply Server","db18p1","N" "g92sukn9vaduv",0,"INSERT INTO sys.streams$_apply_progress (apply#, source_db_name, xidusn, xidslt, xidsqn, commit_scn, commit_position, transaction_id) VALUES (1, 'NULL', :1, :2, :3, :4, :5, :6)","GoldenGate",0,2,119,"2019-06-10/12:23:53",19-06-10,"OGG$R11 - Apply Server","db18p1","N" "9vyxjaht16r7v",0," INSERT /*+ restrict_all_ref_cons */ INTO ""GGTEST"".""T2"" (""A"",""B"",""C"",""D"") VALUES (:1 ,:2 ,:3 ,:4 )","GoldenGate",0,2,1,"2019-06-10/12:27:25",19-06-10,"OGG$R11 - Apply Server","db18p1","N" "ghjk279rcm16p",3903122721,"UPDATE SYS.STREAMS$_APPLY_MILESTONE SET OLDEST_SCN=:1, COMMIT_SCN=:2,SYNCH_SCN=:3, SPARE1=:4, EPOCH=:5, PROCESSED_SCN=:6, APPLY_TIME=:7,APPLIED_MESSAGE_CREATE_TIME=:8, START_SCN=:9, OLDEST_TRANSACTION_ID=:10,LWM_EXTERNAL_POS=:11, OLDEST_POSITION=:12, PROCESSED_POSITION=:13,START_POSITION=:14, OLDEST_CREATE_TIME=:15, XOUT_PROCESSED_POSITION=:16,XOUT_PROCESSED_CREATE_TIME=:17, XOUT_PROCESSED_TID=:18,APPLIED_HIGH_POSITION=:19, XOUT_PROCESSED_TIME=:20, SPARE5=:21, PTO_RECOVERY_SCN=:22,PTO_RECOVERY_INCARNATION=DECODE(:23,PTO_RECOVERY_SCN, PTO_RECOVERY_INCARNATION, (select incarnation# from v$database_incarnation where status = 'CURRENT')) WHERE APPLY#=:24","GoldenGate",0,6,4,"2019-06-10/12:23:54",19-06-10,"OGG$R11 - Apply Server","db18p1","N" "0913ps7wxvf0h",559339712," UPDATE /*+ restrict_all_ref_cons */ ""GGTEST"".""T1"" SET ""B""=:1 WHERE ""A""=:2 ","GoldenGate",0,6,1,"2019-06-10/12:55:15",19-06-10,"OGG$R11 - Apply Server","db18p1","N" "0913ps7wxvf0h",1027040727," UPDATE /*+ restrict_all_ref_cons */ ""GGTEST"".""T1"" SET ""B""=:1 WHERE ""A""=:2 ","GoldenGate",0,6,1,"2019-06-10/12:55:15",19-06-10,"OGG$R11 - Apply Server","db18p1","N" 6行が選択されました。 --- ### TDEで暗号化された表領域をトランスポータブル表領域(TTS)で移行する date: 2019-03-09 url: https://zatoima.github.io/oracle-migration-tde-tts.html tags: Oracle 暗号化表領域の作成 CREATE TABLESPACE tdedata DATAFILE '/u01/app/oracle/oradata/db121s/tdedata.dbf' SIZE 1000M EXTENT MANAGEMENT LOCAL UNIFORM SIZE 1M SEGMENT SPACE MANAGEMENT AUTO ENCRYPTION USING 'AES256' DEFAULT STORAGE (ENCRYPT); 表領域の暗号化確認 set pages 2000 lin 2000 col TABLESPACE_NAME for a15 col EXTENT_MANAGEMENT for a17 col ALLOCATION_TYPE for a15 col SEGMENT_SPACE_MANAGEMENT for a25 col BIGFILE for a6 col ENCRYPTED for a9 SELECT TABLESPACE_NAME ,INITIAL_EXTENT ,MAX_SIZE ,STATUS ,EXTENT_MANAGEMENT ,ALLOCATION_TYPE ,SEGMENT_SPACE_MANAGEMENT ,BIGFILE ,ENCRYPTED FROM DBA_TABLESPACES where TABLESPACE_NAME='TDEDATA' ORDER BY 1; データ移行用のユーザを作成する create user iko identified by oracle DEFAULT TABLESPACE TDEDATA; grant dba to iko; 移行用のテストテーブルを作成&テストデータを挿入 conn iko/oracle create table t1(a number primary key,b number ,c varchar2(30)); declare v_c1 number; v_c2 number; v_c3 varchar2(30); begin dbms_random.seed(uid); for i in 1..1000 loop v_c1 := i; v_c2 := i; v_c3 := dbms_random.string('x', 16); insert into t1 (a, b, c) values (v_c1, v_c2, v_c3); if (mod(i, 100) = 0) then commit; end if; end loop; commit; end; / select count(*) from iko.t1; exit マスター暗号化鍵のエクスポート sqlplus / as sysdba select * from v$encryption_wallet; select ACTIVATING_PDBNAME,tag,key_id,con_id,CREATION_TIME,ACTIVATION_TIME from v$encryption_keys; administer key management export encryption keys with secret "my_secret" to '/home/oracle/export_TDE.exp' identified by oracle; 移行する表領域をread onlyに変更する alter tablespace tdedata read only; exit transport_tablespaces付きでexpdpする(メタデータをエクスポート) expdp system/oracle DUMPFILE=tdedata_tts.dmp DIRECTORY=homedir transport_tablespaces=tdedata TDE用のキーストアとデータファイルをターゲット側のデータベースにコピーする cp /u01/app/oracle/oradata/db121s/tdedata.dbf /u01/app/oracle/oradata/db121t/ cp /keystore/db121s/ewallet.p12 /keystore/db121t マスター暗号化鍵のインポート(ターゲットDB) sqlplus / as sysdba select INST_ID, WRL_TYPE, WRL_PARAMETER, STATUS, WALLET_TYPE from GV$ENCRYPTION_WALLET order by 1; select * from v$encryption_wallet; administer key management import keys with secret "my_secret" from '/home/oracle/export_TDE.exp' identified by oracle with backup; select ACTIVATING_PDBNAME,tag,key_id,con_id,CREATION_TIME,ACTIVATION_TIME from v$encryption_keys; select * from v$encryption_wallet; マスター暗号化鍵を作成 administer key management set key identified by "oracle" with backup; select ACTIVATING_PDBNAME,tag,key_id,con_id,CREATION_TIME,ACTIVATION_TIME from v$encryption_keys; データ移行用のユーザを作成する create user iko identified by oracle; grant dba to iko; ターゲット側で、メタデータをインポート impdp system/oracle dumpfile=tdedata_tts.dmp directory=homedir transport_datafiles=/u01/app/oracle/oradata/db121t/tdedata.dbf transport_tablespaces付きでexpdpする(メタデータをエクスポート) conn / as sysdba alter tablespace tdedata read write; テストデータの確認 select count(*) from iko.t1; --- ### RMANのduplicateコマンドでDBを複製する date: 2019-03-06 url: https://zatoima.github.io/oracle-rman-ruplicate.html tags: Oracle はじめに データベースの複製パターンには下記4つのパターンがあります。 システム的な要件によって選べる選択肢が変わってくると思います。 今回の例では4.の「ターゲットまたはリカバリ・カタログへの接続なしで実行するバックアップベースの複製」で実施しています。 アクティブな複製 オープン状態またはマウント状態のデータベースから直接複製します。 ターゲット接続なしで実行するバックアップベースの複製 RMANは、既存のRMANバックアップおよびコピーから複製ファイルを作成します。 この形式では、補助インスタンスおよびリカバリ・カタログへの接続が必要 ターゲット接続を指定したバックアップベースの複製 既存のRMANバックアップおよびコピーから複製ファイルを作成します。 ターゲットまたはリカバリ・カタログへの接続なしで実行するバックアップベースの複製 BACKUP LOCATIONで指定した場所に配置されたRMANバックアップおよびコピーから複製ファイルを作成 RMANバックアップからリストア・リカバリする場合もデータベースの複製となりますが、今回の例では含んでいません。 環境構成 同一筐体内に複製する手順となります。 No データベース名 DBバージョン 備考 1 db121s 12.1.0.2 複製元 2 db121t 12.1.0.2 複製先 複製元でRMANバックアップの取得 rman target / run { BACKUP INCREMENTAL LEVEL 0 DATABASE FORMAT '/home/oracle/rman/db121s/full_%d_%T_%U' SPFILE PLUS ARCHIVELOG FORMAT '/home/oracle/rman/db121s/ARCH_%d_%T_%U'; BACKUP AS COPY CURRENT CONTROLFILE FORMAT '/home/oracle/rman/db121s/CNT_%d_%T_%U.ctl'; } 複製先のクリーンアップ rm -rf /u01/app/oracle/oradata/DB121T/* 複製先パラメータファイル作成 複製元のデータベースに接続し、spfileから編集用のpfileを作成する。 . /home/oracle/.oraenv_db121s sqlplus / as sysdba create pfile='/tmp/initdb121t.ora' from spfile; exit 複製先パラメータファイル編集 複製元に依存する値を複製先に記載を変更する。(例:db_nameは「db121s」から「db121t」へ) vi /tmp/initdb121t.ora 以下のパラメータの値を変更する ・*.cluster_database : false ・*.control_files : /u01/app/oracle/oradata/db121t ・*.db_name : db121t ・*.db_unique_name : db121t ・*.dispatchers : (PROTOCOL=TCP) (SERVICE=db121tXDB) 以下のパラメータの値を追加する *.DB_FILE_NAME_CONVERT='/u01/app/oracle/oradata/DB121S/datafile/','/u01/app/oracle/oradata/DB121T/datafile/' *.LOG_FILE_NAME_CONVERT='/u01/app/oracle/oradata/DB121S/onlinelog/','/u01/app/oracle/oradata/DB121T/onlinelog' 補助インスタンス起動 . /home/oracle/.oraenv_db121t sqlplus / as sysdba startup nomount pfile='/tmp/initdb121t.ora' spfileの作成 create spfile = '/u01/app/oracle/product/12.1.0.2/dbhome_2/dbs/spfiledb121t.ora' from pfile='/tmp/initdb121t.ora'; exit 複製コマンドの実施 rman auxiliary / run { duplicate database to db121t backup location '/home/oracle/rman/db121s'; } RMANのduplicateコマンドの詳細についてはマニュアルをご確認ください。 Oracle® Databaseバックアップおよびリカバリ・リファレンス 12cリリース1 (12.1) https://docs.oracle.com/cd/E57425_01/121/RCMRF/rcmsynta020.htm DUPLICATE --- ### Data Pump(expdp/impdp)使用時のコマンドとオプション date: 2019-03-04 url: https://zatoima.github.io/oracle-datapump-command.html tags: Oracle Data Pumpを使うときはTABLE単位かSCHEMA単位が多いのでそのほかのモードとオプション含めて簡単に整理した。 expdp -- database単位 expdp iko/oracle DIRECTORY=homedir dumpfile=db.dmp REUSE_DUMPFILES=YES full=y -- tablespace単位 expdp iko/oracle DIRECTORY=homedir dumpfile=ts.dmp REUSE_DUMPFILES=YES tablespaces=TSDATA -- schema単位 expdp iko/oracle DIRECTORY=homedir dumpfile=schema.dmp REUSE_DUMPFILES=YES schemas=iko -- table単位 expdp iko/oracle DIRECTORY=homedir dumpfile=table.dmp REUSE_DUMPFILES=YES tables=iko.t1 https://docs.oracle.com/cd/E57425_01/121/SUTIL/toc.htm エクスポート・ユーティリティのコマンドライン・モードで使用可能なパラメータ パラメータ 説明 directory dmpファイルを作成するディレクトリを、DIRECTORYオブジェクト名で指定する dumpfile dmpファイル名を指定する logfile dmp時のログファイル名を指定する content expdp対象を指定する data_only:表のデータのみ metadata_only:オブジェクト定義のみ all:定義とデータ(デフォルト) estimate ジョブ見積りを算出します。見積もりに使用するメソッドを指定 estimate_only expdpを実行せず、ディスク容量の見積りだけ行う exclude expdpから除外したいオブジェクトを指定する reuse_dumpfiles dmpファイルの上書きオプション。expdp先にファイルが存在する場合は上書きする filesize 各dmpファイルのサイズをバイト単位で指定 remap_data データ変換ファンクションを指定 compression dmpファイルを圧縮する。ALL, DATA_ONLY, METADATA_ONLY, NONE encryption dmpファイルの一部またはすべてを暗号化 ALL, DATA_ONLY, ENCRYPTED_COLUMNS_ONLY, METADATA_ONLY, NONE encryption_algorithm 暗号化の方法を指定(AES128, AES192, AES256) encryption_mode 暗号化キーの生成方法。 DUAL, PASSWORD, TRANSPARENT encryption_password dmpファイル内に暗号化データを作成するためのパスワード flashback_scn expdp時点をSCNで指定するUNDOにデータが残っている必要がある impdp -- database単位 impdp iko/oracle DIRECTORY=homedir dumpfile=db.dmp TABLE_EXISTS_ACTION=REPLACE full=y -- tablespace単位 impdp iko/oracle DIRECTORY=homedir dumpfile=ts.dmp TABLE_EXISTS_ACTION=REPLACE tablespaces=JRADATA -- schemas単位 impdp iko/oracle DIRECTORY=homedir dumpfile=schema.dmp schemas=iko -- table単位 impdp iko/oracle DIRECTORY=homedir dumpfile=table.dmp tables=iko.insert_t1 https://docs.oracle.com/cd/E57425_01/121/SUTIL/toc.htm インポート・ユーティリティのコマンドライン・モードで使用可能なパラメータ パラメータ 説明 備考 remap_schema 異なるスキーマへimpdpする場合に指定する remap_tablespace 異なる表領域へimpdpする場合に指定する directory impdpファイルが置いてあるディレクトリを、DIRECTORYオブジェクト名で指定する expdpと同様 dumpfile impdpファイルのファイル名を指定する expdpと同様 logfile impdp時のログファイル名を指定する expdpと同様 content impdp対象を指定する data_only:表のデータのみ metadata_only:オブジェクト定義のみ all:定義とデータ(デフォルト) expdpと同様 exclude impdpから除外したいのオブジェクトを指定する expdpと同様 table_exists_action impdp先に既に定義やデータが存在した場合の動きを指定する SKIP | APPEND | TRUNCATE | REPLACE 表オブジェクトだけを対象とする encryption_password expdp時にパスワードセットした場合に使用する --- ### Oracle Databaseの表領域使用率を確認するSQL date: 2019-02-28 url: https://zatoima.github.io/oracle-tablespace-capacitycheck.html tags: Oracle, SQL 表領域使用率を確認するSQL set pages 2000 lin 2000 col name for a15 SELECT t.tablespace_name name , t.status , t.contents type , t.extent_management extmgt , t.allocation_type alloc , t.initial_extent/1024 init_kb , t.segment_space_management segmgt , TO_CHAR(NVL(d.bytes - NVL(f.bytes, 0), 0)/1024/1024, '9,999,990.9') "USED(MB)" , TO_CHAR(NVL(d.bytes, 0)/1024/1024, '9,999,990.9') "TOTAL(MB)" , TO_CHAR(NVL(d.bytes - NVL(f.bytes, 0), 0)/(NVL(d.bytes, -1)/100), '990.0') "USED(%)" FROM dba_tablespaces t , (SELECT tablespace_name, SUM(bytes) bytes FROM dba_data_files GROUP BY tablespace_name) d , (SELECT tablespace_name, SUM(bytes) bytes FROM dba_free_space GROUP BY tablespace_name) f WHERE t.tablespace_name = d.tablespace_name(+) AND t.tablespace_name = f.tablespace_name(+) AND NOT (t.extent_management = 'LOCAL' AND t.contents = 'TEMPORARY') UNION ALL SELECT t.tablespace_name name , t.status , t.contents type , t.extent_management extmgt , t.allocation_type alloc , t.initial_extent/1024 init_kb , t.segment_space_management segmgt , TO_CHAR(NVL(f.bytes, 0)/1024/1024, '9,999,990.9') "USED(MB)" , TO_CHAR(NVL(d.bytes, 0)/1024/1024, '9,999,990.9') "TOTAL(MB)" , TO_CHAR(NVL(f.bytes/(d.bytes/100), 0), '990.0') "USED(%)" FROM dba_tablespaces t , (SELECT tablespace_name, SUM(bytes) bytes FROM dba_temp_files GROUP BY tablespace_name) d , (SELECT tablespace_name, SUM(bytes_cached) bytes FROM v$temp_extent_pool GROUP BY tablespace_name) f WHERE t.tablespace_name = d.tablespace_name(+) AND t.tablespace_name = f.tablespace_name(+) AND t.extent_management = 'LOCAL' AND t.contents = 'TEMPORARY' ORDER BY name ; 結果 NAME STATUS TYPE EXTMGT ALLOC INIT_KB SEGMGT USED(MB) TOTAL(MB) USED(% --------------- --------- --------------------- ---------- --------- ---------- ------ ------------ ------------ ------ GG_DATA ONLINE PERMANENT LOCAL SYSTEM 64 AUTO 1.0 5,120.0 0.0 SYSAUX ONLINE PERMANENT LOCAL SYSTEM 64 AUTO 2,400.6 2,530.0 94.9 SYSTEM ONLINE PERMANENT LOCAL SYSTEM 64 MANUAL 897.4 900.0 99.7 TEMP ONLINE TEMPORARY LOCAL UNIFORM 1024 MANUAL 597.0 200.0 298.5 UNDOTBS1 ONLINE UNDO LOCAL SYSTEM 64 MANUAL 12.3 320.0 3.8 USERS ONLINE PERMANENT LOCAL SYSTEM 64 AUTO 1.0 5.0 20.0 6行が選択されました。 SQL> --- ### Oracle Databaseで透過的データベース暗号化(Transparent Data Encryption(TDE))の設定・構築を行う date: 2019-02-23 url: https://zatoima.github.io/oracle-tde-implement.html tags: Oracle 今回は、Oracle Database 12cR1 において設定を行います。 透過的データベース暗号化(Transparent Data Encryption(TDE))は、データベース内の保存データを暗号化することによって、機密データを保護します。 データベースの物理ファイルを暗号化することにより、保存データを暗号化します。 データはストレージに書き込まれる前に自動的に暗号化され、ストレージから読み込まれる時に自動的に複合化されます。 マニュアルはこちら Oracle® Database Advanced Securityガイド 12cリリース1 (12.1) https://docs.oracle.com/cd/E57425_01/121/ASOAG/toc.htm 概要説明はこちら Transparent Data Encryption https://www.oracle.com/technetwork/jp/database/security/index-099011-ja.html Oracle Advanced Securityの透過的データベース暗号化(Transparent Data Encryption(TDE))は、保存されているデータをデータベース・レイヤーで暗号化することで、潜在的な攻撃者がデータベースをバイパスしてストレージから機密情報を読み取ることを阻止します。 データベース認証が済んだアプリケーションおよびユーザーは、(アプリケーション・コードまたは構成変更なしで)透過的にアプリケーション・データへのアクセスを維持することができますが、表領域ファイルから機密データを読み取ろうとするOSユーザーによる攻撃や、盗み取ったディスクまたはバックアップから情報を読み取ろうとする窃盗犯の攻撃によるクリアテキスト・データへのアクセスは拒否されます。 暗号化鍵アーキテクチャは2層に分かれているため、鍵の管理が容易で、鍵と暗号化データの明確な分離が可能です。また、アシスト付き鍵ローテーション機能があり、データを再暗号化する必要はありません。キーストアの管理には、Oracle Enterprise Managerの便利なWebコンソールまたはコマンドラインを使用できます。 keystoreを格納するディレクトリ作成 今回は同サーバ上にディレクトリを作成します。 su - mkdir -p /keystore/dbvms chown -R oracle:oinstall /keystore chmod -R 755 /keystore sqlnet.oraに記載する ENCRYPTION_WALLET_LOCATIONを記載します。 vi $ORACLE_HOME/network/admin/sqlnet.ora ENCRYPTION_WALLET_LOCATION= (SOURCE= (METHOD=FILE) (METHOD_DATA= (DIRECTORY=/keystore/$ORACLE_UNQNAME))) 環境変数に ORACLE_UNQNAME を記載する。 ※ $ORACLE_UNQNAMEをENCRYPTION_WALLET_LOCATIONに使用しているため設定しています。 vi .oraenv_dbvms export ORACLE_UNQNAME=dbvms TDEキーストアの作成 . /home/oracle/.oraenv_dbvms sqlplus / as sysdba administer key management create keystore '/keystore/dbvms' identified by "oracle"; 【コマンド結果】 SQL> administer key management create keystore '/keystore/dbvms' identified by "oracle"; キーストアが変更されました。 SQL> TDEキーストアのオープン administer key management set keystore open identified by "oracle"; 【コマンド結果】 SQL> administer key management set keystore open identified by "oracle"; キーストアが変更されました。 TDEキーストアのオープン確認 set pages 2000 lin 2000 col WRL_TYPE for a8 col WRL_PARAMETER for a30 col STATUS for a30 col WALLET_TYPE for a30 select INST_ID, WRL_TYPE, WRL_PARAMETER, STATUS, WALLET_TYPE from GV$ENCRYPTION_WALLET order by 1; 【コマンド結果】 INST_ID WRL_TYPE WRL_PARAMETER STATUS WALLET_TYPE ---------- -------- ------------------------------ ------------------------------ ------------------------------ 1 FILE /keystore/dbvms/ OPEN_NO_MASTER_KEY PASSWORD SQL> TDEマスター暗号化鍵の作成 administer key management set key identified by "oracle" with backup using 'deploy'; 【コマンド結果】 SQL> administer key management set key identified by "oracle" with backup using 'deploy'; キーストアが変更されました。 SQL> TDEマスター暗号化鍵の確認 alter session set nls_timestamp_tz_format = 'yyyy/mm/dd hh24:mi:ss'; col CREATOR_DBNAME for a15 col KEY_ID for a60 col CREATION_TIME for a20 col ACTIVATION_TIME for a20 select CREATOR_DBNAME, KEY_ID, CREATION_TIME, ACTIVATION_TIME from V$ENCRYPTION_KEYS order by 1,2; 【コマンド結果】 CREATOR_DBNAME KEY_ID CREATION_TIME ACTIVATION_TIME --------------- ------------------------------------------------------------ -------------------- -------------------- dbvms AccLZFJI/U95v/XKfMIdMWIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 2019/03/08 07:52:37 2019/03/08 07:52:37 SQL> 自動ログイン・キーストア作成 administer key management create auto_login keystore from keystore '/keystore/dbvms' identified by "oracle"; DB再起動 shutdown immediate startup exit 自動ログインキーストアのオープン状態確認 列 STATUS が “OPEN”、列 WALLET_TYPE が “AUTOLOGIN” となっていること sqlplus / as sysdba set lines 200 col WRL_TYPE for a8 col WRL_PARAMETER for a60 col STATUS for a6 col WALLET_TYPE for a15 select INST_ID, WRL_TYPE, WRL_PARAMETER, STATUS, WALLET_TYPE from GV$ENCRYPTION_WALLET order by 1; exit 【コマンド結果】 INST_ID WRL_TYPE WRL_PARAMETER STATUS WALLET_TYPE ---------- -------- ------------------------------------------------------------ ------ --------------- 1 FILE /keystore/dbvms/ OPEN AUTOLOGIN 暗号化表領域の作成 CREATE TABLESPACE dbdata DATAFILE '/u01/app/oracle/oradata/dbvms/dbdata.dbf' SIZE 3000M EXTENT MANAGEMENT LOCAL UNIFORM SIZE 1M SEGMENT SPACE MANAGEMENT AUTO ENCRYPTION USING 'AES256' DEFAULT STORAGE (ENCRYPT); 表領域の確認 set pages 2000 lin 2000 col TABLESPACE_NAME for a15 col EXTENT_MANAGEMENT for a17 col ALLOCATION_TYPE for a15 col SEGMENT_SPACE_MANAGEMENT for a25 col BIGFILE for a6 col ENCRYPTED for a9 SELECT TABLESPACE_NAME ,INITIAL_EXTENT ,MAX_SIZE ,STATUS ,EXTENT_MANAGEMENT ,ALLOCATION_TYPE ,SEGMENT_SPACE_MANAGEMENT ,BIGFILE ,ENCRYPTED FROM DBA_TABLESPACES ORDER BY 1; 【コマンド結果】 TABLESPACE_NAME INITIAL_EXTENT MAX_SIZE STATUS EXTENT_MANAGEMENT ALLOCATION_TYPE SEGMENT_SPACE_MANAGEMENT BIGFIL ENCRYPTED --------------- -------------- ---------- ------ ----------------- --------------- ------------------------- ------ --------- dbdata 1048576 2147483645 ONLINE LOCAL UNIFORM AUTO NO YES SYSAUX 65536 2147483645 ONLINE LOCAL SYSTEM AUTO NO NO SYSTEM 65536 2147483645 ONLINE LOCAL SYSTEM MANUAL NO NO TEMP 1048576 2147483645 ONLINE LOCAL UNIFORM MANUAL NO NO UNDOTBS1 65536 2147483645 ONLINE LOCAL SYSTEM MANUAL NO NO USERS 65536 2147483645 ONLINE LOCAL SYSTEM AUTO NO NO データ・ファイルの確認 col TABLESPACE_NAME for a15 col FILE_NAME for a70 col AUTOEXTENSIBLE for a15 col ONLINE_STATUS for a15 SELECT TABLESPACE_NAME ,FILE_NAME ,BYTES/1024/1024 MB ,AUTOEXTENSIBLE ,STATUS ,ONLINE_STATUS FROM DBA_DATA_FILES ORDER BY 1; 物理的な暗号化表領域の確認 テーブルを作成する create table CHECK_ENCRYPT_TABLE(COL1 number, COL2 VARCHAR2(40)) tablespace dbdata; insert into CHECK_ENCRYPT_TABLE values (1,'CHECK_ENCRYPT_VALUE'); commit; データファイルに反映されるように複数回ログスイッチを行う alter system switch logfile; exit 物理的な暗号化を確認する。CHECK_ENCRYPT_VALUEという文言がないかどうか確認する strings '/u01/app/oracle/oradata/dbvms/dbdata.dbf' | grep CHECK_ENCRYPT_VALUE --- ### GoldenGate関連プロセスのsession情報を確認する方法 date: 2019-02-16 url: https://zatoima.github.io/goldengate-check-session-info.html tags: GoldenGate, Oracle moduleで対象プロセスを絞り込む Integrated Capture/Replicatの場合は、GoldenGateプロセスもDB内のプロセスのため、module列で絞り込んで出力することが出来る。 SELECT s.inst_id, s.con_id, s.logon_time, s.sid, s.serial#, s.module, p.spid, p.pid, s.action, s.process, s.program, s.status, s.action, DECODE(s.server,'DEDICATED','DED','SHR') SVR, s.STATE, s.event FROM gv$session s, v$process p WHERE (s.module = 'GoldenGate' OR s.module LIKE '%tream%' OR s.module LIKE 'OGG%') AND p.addr=s.paddr ORDER BY s.con_id, s.inst_id, s.module, s.action; 出力結果例 ターゲット側で実行しているため、Integrated Replicatのプロセスのみ。 Action列で、「Coordinator」、「Receiver」、「Reader」、「Apply Server」か判別可能。 INST_ID CON_ID LOGON_TIME SID SERIAL# MODULE SPID PID ACTION PROCESS PROGRAM STATUS ACTION SVR STATE EVENT 1 0 2019/3/3 339 34151 Streams 28703 59 AQ LB Coordinator 28703 oracle@xxxxxxx1t.jp.oracle.com (QM03) ACTIVE AQ LB Coordinator DED WAITING Streams AQ: load balancer idle 1 0 2019/3/3 23 462 Streams 27781 57 QMON Coordinator 27781 oracle@xxxxxxx1t.jp.oracle.com (QM02) ACTIVE QMON Coordinator DED WAITING Streams AQ: qmn coordinator idle wait 1 0 2019/3/3 25 58083 Streams 27787 60 QMON Slave 27787 oracle@xxxxxxx1t.jp.oracle.com (Q003) ACTIVE QMON Slave DED WAITING Streams AQ: waiting for time management or cleanup tasks 1 0 2019/3/3 177 6407 Streams 27789 61 QMON Slave 27789 oracle@xxxxxxx1t.jp.oracle.com (Q004) ACTIVE QMON Slave DED WAITING Streams AQ: qmn slave idle wait 1 0 2019/3/3 182 19018 Streams 27829 67 QMON Slave 27829 oracle@xxxxxxx1t.jp.oracle.com (Q006) ACTIVE QMON Slave DED WAITING Streams AQ: qmn slave idle wait 1 3 2019/3/3 33 20930 GoldenGate 28053 75 OGG$R11 - Apply Coordinator 28053 oracle@xxxxxxx1t.jp.oracle.com (AP01) ACTIVE OGG$R11 - Apply Coordinator DED WAITING rdbms ipc message 1 3 2019/3/3 176 19252 GoldenGate 28055 76 OGG$R11 - Apply Reader 28055 oracle@xxxxxxx1t.jp.oracle.com (AS01) ACTIVE OGG$R11 - Apply Reader DED WAITING REPL Capture/Apply: messages 1 3 2019/3/3 350 51690 GoldenGate 28051 74 OGG$R11 - Apply Receiver 28047 replicat@xxxxxxx1t.jp.oracle.com (TNS V1-V3) INACTIVE OGG$R11 - Apply Receiver DED WAITING SQL*Net message from client 1 3 2019/3/3 349 48410 GoldenGate 28057 77 OGG$R11 - Apply Server 28057 oracle@xxxxxxx1t.jp.oracle.com (AS02) ACTIVE OGG$R11 - Apply Server DED WAITING rdbms ipc message 1 3 2019/3/3 35 16249 GoldenGate 28059 78 OGG$R11 - Apply Server 28059 oracle@xxxxxxx1t.jp.oracle.com (AS03) ACTIVE OGG$R11 - Apply Server DED WAITING rdbms ipc message 1 3 2019/3/3 184 29507 GoldenGate 28061 79 OGG$R11 - Apply Server 28061 oracle@xxxxxxx1t.jp.oracle.com (AS04) ACTIVE OGG$R11 - Apply Server DED WAITING rdbms ipc message 1 3 2019/3/3 352 60489 GoldenGate 28063 80 OGG$R11 - Apply Server 28063 oracle@xxxxxxx1t.jp.oracle.com (AS05) ACTIVE OGG$R11 - Apply Server DED WAITING rdbms ipc message --- ### Linuxユーザの$HOME配下の日本語デフォルトディレクトリを移動させる date: 2019-02-13 url: https://zatoima.github.io/linux-home-directory-move.html tags: Linux Oracle LinuxやCentOS、Red Hat OSを日本語環境でインストールした場合、ユーザの$HOME配下に日本語ディレクトリが存在するが、使用しないディレクトリのため他ディレクトリに退避する。あと日本語表記から英語表記に変更する ・作業前のディレクトリ構成 [oracle]$ pwd /home/oracle [oracle]$ ls -l 合計 36 drwxr-xr-x. 2 oracle oinstall 4096 1月 24 11:34 2019 tmp drwxr-xr-x. 2 oracle oinstall 4096 1月 24 11:33 2019 ダウンロード drwxr-xr-x. 2 oracle oinstall 4096 1月 24 11:33 2019 テンプレート drwxr-xr-x. 2 oracle oinstall 4096 1月 24 11:33 2019 デスクトップ drwxr-xr-x. 2 oracle oinstall 4096 1月 24 11:33 2019 ドキュメント drwxr-xr-x. 2 oracle oinstall 4096 1月 24 11:33 2019 ビデオ drwxr-xr-x. 2 oracle oinstall 4096 1月 24 11:33 2019 音楽 drwxr-xr-x. 2 oracle oinstall 4096 1月 24 11:33 2019 画像 drwxr-xr-x. 2 oracle oinstall 4096 1月 24 11:33 2019 公開 [oracle]$ 次に/.config/user-dirs.dirs の ファイルを修正。 vi/.config/user-dirs.dirs ・修正前 XDG_DESKTOP_DIR="$HOME/デスクトップ" XDG_DOWNLOAD_DIR="$HOME/ダウンロード" XDG_TEMPLATES_DIR="$HOME/テンプレート" XDG_PUBLICSHARE_DIR="$HOME/公開" XDG_DOCUMENTS_DIR="$HOME/ドキュメント" XDG_MUSIC_DIR="$HOME/音楽" XDG_PICTURES_DIR="$HOME/画像" XDG_VIDEOS_DIR="$HOME/ビデオ" ・修正後 .Desktop配下に移動。このタイミングでディレクトリ名を日本語から英語に変更。 XDG_DESKTOP_DIR="$HOME/.Desktop" XDG_DOWNLOAD_DIR="$HOME/.Desktop/Download" XDG_TEMPLATES_DIR="$HOME/.Desktop/Templates" XDG_PUBLICSHARE_DIR="$HOME/.Desktop/Publicshare" XDG_DOCUMENTS_DIR="$HOME/.Desktop/Documents" XDG_MUSIC_DIR="$HOME/.Desktop/Music" XDG_PICTURES_DIR="$HOME/.Desktop/Pictures" XDG_VIDEOS_DIR="$HOME/.Desktop/Videos" 新しい配置場所のディレクトリを作成。 mkdir -p $HOME/.Desktop mkdir -p $HOME/.Desktop/Documents mkdir -p $HOME/.Desktop/Download mkdir -p $HOME/.Desktop/Templates mkdir -p $HOME/.Desktop/Publicshare mkdir -p $HOME/.Desktop/Music mkdir -p $HOME/.Desktop/Pictures mkdir -p $HOME/.Desktop/Videos 不要になったディレクトリを削除。 rm -rf "ダウンロード" "テンプレート" "デスクトップ" "ドキュメント" "ビデオ" "音楽" "画像" "公開" ユーザでログアウトして再度ログインして完了。 --- ### AWR(DBA_HIST表)を使用した確認SQL date: 2019-01-21 url: https://zatoima.github.io/oracle-awr-checksql/ tags: Oracle, AWR はじめに AWR(Automatic Workload Repository)とはOracle Databaseの稼働統計とワークロード情報のスナップショットを自動的に収集・管理する機能です。 一般的にAWRを使用した分析はAWRレポートをhtml形式、text形式で出力してレポートからパフォーマンスや稼働統計を確認して分析、改善案を整理します。 AWRレポートを出力する際には各種ディクショナリ(DBA_HIST表)を参照することからそのディクショナリを直接見て色々な分析を行うことが出来ます。 AWR利用には「Diagnostic Pack」のライセンスが追加で必要になります。 AWRに格納された過去のSQL監視結果をレポートする(Oracle 12c~) SELECT report_id, GENERATION_TIME, key1 FROM dba_hist_reports WHERE component_name='sqlmonitor' AND key1='5j5wp4d5s9pqz'; AWRに格納されているSQLを確認する select a.begin_interval_time, b.sql_id, c.sql_text from DBA_HIST_SNAPSHOT a, DBA_HIST_SQLSTAT st, DBA_HIST_SQLTEXT c where a.dbid=b.dbid and a.instance_number=b.instance_number and a.snap_id=b.snap_id and b.dbid=c.dbid and b.sql_id=c.sql_id and c.sql_text like '%<検索SQL>%'; AWRに格納された過去のSQL監視結果をレポートする(Oracle 12c~) SELECT report_id, GENERATION_TIME, key1 FROM dba_hist_reports WHERE component_name='sqlmonitor' AND key1='5j5wp4d5s9pqz'; AWR snapshotの確認 SELECT DBID , SNAP_ID , MIN(TO_CHAR(BEGIN_INTERVAL_TIME, 'YYYY/MM/DD HH24:MI:SS')) AS BEGIN_INTERVAL_TIME , MIN(TO_CHAR(END_INTERVAL_TIME , 'YYYY/MM/DD HH24:MI:SS')) AS END_INTERVAL_TIME FROM DBA_HIST_SNAPSHOT WHERE DBID = xxxxxxxxx GROUP BY DBID , SNAP_ID ORDER BY 1,2,3,4; dba_undo_statから長時間実行されているSQL等の確認(累積) select MAXQUERYSQLID,sum(MAXQUERYLEN) from dba_hist_undostat where dbid='xxxxxxxxx' AND BEGIN_TIME >= TO_TIMESTAMP('2016/02/10 20:00:00', 'YYYY/MM/DD HH24:MI:SS') AND END_TIME <= TO_TIMESTAMP('2016/10/31 20:15:00', 'YYYY/MM/DD HH24:MI:SS') group by MAXQUERYSQLID order by 2; dba_undo_statから長時間実行されているSQL等の確認(個別) select MAXQUERYSQLID,sum(MAXQUERYLEN) from dba_hist_undostat where dbid='xxxxxxxxx' AND BEGIN_TIME >= TO_TIMESTAMP('2016/02/10 20:00:00', 'YYYY/MM/DD HH24:MI:SS') AND END_TIME <= TO_TIMESTAMP('2016/10/31 20:15:00', 'YYYY/MM/DD HH24:MI:SS') group by MAXQUERYSQLID order by 2; AWRから共有プールの拡張履歴を確認する col CURRENT_SIZE for 999,999,999,999,999 col MIN_SIZE for 999,999,999,999,999 col MAX_SIZE for 999,999,999,999,999 col USER_SPECIFIED_SIZE for 999,999,999,999,999 col COMPONENT for a30 col diff for 999,999,999,999,999 set pages 20000 set lin 20000 alter session set NLS_DATE_FORMAT='YYYY/MM/DD HH24:MI:SS'; select * from DBA_HIST_MEM_DYNAMIC_COMP where LAST_OPER_MODE = 'IMMEDIATE' and dbid=xxxxxxxxx order by LAST_OPER_TIME desc; select * from DBA_HIST_MEM_DYNAMIC_COMP where LAST_OPER_MODE = 'DEFERRED' and dbid=xxxxxxxxx order by LAST_OPER_TIME; SQL_IDを指定し、実行時間を取得するSQL select sql_id,sum(EXECUTIONS_DELTA),sum(ELAPSED_TIME_DELTA) ,round(sum(ELAPSED_TIME_DELTA)/sum(EXECUTIONS_DELTA)/100000,0) sec from dba_hist_sqlstat natural join dba_hist_snapshot where sql_id in ( '2znznu2dkbjq1' , '39up7r1bnk3mn' , '5wna3gkz7wx7v' ) AND begin_interval_time between to_timestamp('20160201:00','YYYYMMDD:HH24') AND to_date('20160213:00','YYYYMMDD:HH24') group by sql_id; AWRスナップショットから実行計画を出力 select plan_table_output from table(DBMS_XPLAN.DISPLAY_AWR('ff6uqt4322h9')); AWRの取得・削除 exec dbms_workload_repository.create_snapshot(); exec DBMS_WORKLOAD_REPOSITORY.DROP_SNAPSHOT_RANGE (low_snap_id => 1,high_snap_id => 9999999); --- ### GoldenGateから実行されたSQLを確認する方法(Integrated Replicat) date: 2018-11-11 url: https://zatoima.github.io/goldengate-check-exection-sql/ tags: Oracle, GoldenGate GoldenGateの場合においてもSQLが内部的に実行されており、Oracle Databaseの共有プールに情報が格納されている。 なので、Replicatが動作するターゲット側で下記SQLを実行してどのようなSQLが実行されているか確認出来る。 SELECT sql_id, plan_hash_value, sql_text, module, fetches, command_type, executions, first_load_time, last_active_time, action, service, is_bind_aware FROM V$SQL WHERE module='GoldenGate'; 注意事項 (g)v$sqlのsql_text列は「VARCHAR2(1000)」のため、長過ぎるものはCLOB型のSQL_FULLTEXTで出力。dbms_lob.substrで変換。 バインド変数値を確認する場合は、v$sql_bind_captureから --- ### date: 0001-01-01 url: https://zatoima.github.io/xxxxxx.html tags: xxxx, xxx --- ### GoldenGateパラメータの定義情報の取得(info paramコマンド) date: 0001-01-01 url: https://zatoima.github.io/goldengate-info-param.html tags: Oracle, GoldenGate はじめに info paramコマンドを使用するとGoldenGateのパラメータ定義情報を取得可能です。本機能はGoldenGate12.2のバージョンから使用可能です。 マニュアルはこちら https://docs.oracle.com/cd/E74358_01/gg-winux/GWURF/GUID-60208072-8E74-4703-B4FF-31761E6CDDC0.htm#GUID-60208072-8E74-4703-B4FF-31761E6CDDC0 INFO PARAM INFO PARAMでは、パラメータ定義情報を取得します。名前が複数のレコードに一致した場合、一致したレコードがすべて表示されます。問合せパラメータに子オプションがある場合、各子オプションの名前が「Options」タブにリストされていても、出力には表示されません。オプションのレコード全体を表示するには、parameter.optionという形式の完全名を個別に問い合せる必要があります。 基本的な使い方 下記のようにパラメータ、及びパラメータのサブ・パラメータの情報を取得することが出来ます。 GGSCI (dbvgg.jp.oracle.com) 3> info param BATCHSQL param name : batchsql description : Use the BATCHSQL parameter to increase the performance of Replicat. BATCHSQL causes Replicat to organize similar SQL statements into arrays and apply them at an accelerated rate. In its normal mode, Replicat applies one SQL statement at a time. argument : no argument options : batcherrormode|nobatcherrormode, batchesperqueue, batchtransops bypasspkcheck|nobypasspkcheck, bytesperqueue checkuniquekeys|nocheckuniquekeys errorhandling|noerrorhandling, maxthreadqueuedepth, opsperbatch opsperqueue, thread, trace component(s): REPLICAT mode(s) : all Replicat modes platform(s) : all platforms versions : database(s) : Oracle 8 Oracle 9i Oracle 10g Oracle 11g Oracle 12c Oracle 18c Sybase DB2LUW 10.5 DB2LUW 10.1 DB2LUW 9.5 DB2LUW 9.7 Teradata Timesten DB2 for i DB2 for i Remote MS SQL MS SQL CDC Informix SQL/MX DB2 z/OS PostgreSQL status : current mandatory : false dynamic : false relations : none GGSCI (dbvgg.jp.oracle.com) 4> info param BATCHSQL.opsperbatch param name : batchsql.opsperbatch description : Sets the maximum number of row operations that one batch can contain. After OPSPERBATCH is reached, a target transaction is executed. argument : integer default : 1200 range : 1 - 100000 options : component(s): REPLICAT mode(s) : all Replicat modes platform(s) : all platforms versions : database(s) : Oracle 8 Oracle 9i Oracle 10g Oracle 11g Oracle 12c Oracle 18c Sybase DB2LUW 10.5 DB2LUW 10.1 DB2LUW 9.5 DB2LUW 9.7 Teradata Timesten DB2 for i DB2 for i Remote MS SQL MS SQL CDC Informix SQL/MX DB2 z/OS PostgreSQL status : current mandatory : false dynamic : false relations : none 出力内容 下記のような出力結果が出力されます。 No. 項目 補足 1 param name パラメータ名 2 description パラメータ説明 3 argument 引数 4 options サブパラメータ 5 component 対応コンポーネント (「capture」 or 「data pump」 or 「replicat」) 6 mode Integratedモード or classicモード 7 platform 対応プラットフォーム 8 versions 対応バージョン 9 database 対応データベース 10 status current or deprecated 11 mandatory 必須かどうか? 12 dynamic 動的変更が可能か? 13 relations GoldenGateのバージョン間の出力差異を確認する GoldenGateの12.3以降のバージョンではSYSLOGパラメータが非推奨に変更されています。この変更がどのように出力結果に影響しているか確認してみます。 下記出力結果の「★」印箇所のように「deprecated」に変更されています。GGのアップデート時にパラメータをチェックするのも良いかもですね。 GoldenGate 12.2.0.1の出力結果 [oracle@dbvgg ~]$ ogg1 Oracle GoldenGate Command Interpreter for Oracle Version 12.2.0.1.170919 OGGCORE_12.2.0.1.0OGGBP_PLATFORMS_171030.0908_FBO Linux, x64, 64bit (optimized), Oracle 11g on Oct 30 2017 19:19:45 Operating system character set identified as UTF-8. Copyright (C) 1995, 2017, Oracle and/or its affiliates. All rights reserved. GGSCI (dbvgg.jp.oracle.com) 1> info param syslog param name : syslog description : Use the SYSLOG parameter to control the types of messages that Oracle GoldenGate sends to the system logs on a Windows or UNIX system, or to the SYSOPR message queue on an IBM i system. argument : no argument options : all, error, info, none, warn component(s): MGR GLOBALS mode(s) : none platform(s) : all platforms versions : min ver : 11.1.1 database(s) : all supported databases (on the supported platforms). status : current ★←「current」 mandatory : false dynamic : false relations : none GGSCI (dbvgg.jp.oracle.com) 2> GoldenGate 18.1の出力結果 [oracle@dbvgg ~]$ ogg2 Oracle GoldenGate Command Interpreter for Oracle Version 18.1.0.0.0 OGGCORE_18.1.0.0.0_PLATFORMS_180928.0432_FBO Linux, x64, 64bit (optimized), Oracle 18c on Sep 29 2018 07:21:38 Operating system character set identified as UTF-8. Copyright (C) 1995, 2018, Oracle and/or its affiliates. All rights reserved. GGSCI (dbvgg.jp.oracle.com) 1> info param syslog param name : syslog description : Use the SYSLOG parameter to control the types of messages that Oracle GoldenGate sends to the system logs on a Windows or UNIX system, or to the SYSOPR message queue on an IBM i system. argument : no argument options : all, error, info, none, warn component(s): MGR GLOBALS mode(s) : none platform(s) : all platforms versions : min ver : 11.1.1 database(s) : all supported databases (on the supported platforms). status : deprecated ★←「deprecated」に変更されている mandatory : false dynamic : false relations : none GGSCI (dbvgg.jp.oracle.com) 2>