Hatena::ブログ(Diary)

ablog このページをアンテナに追加 RSSフィード

2017-09-18

sqlplus から Oracle Database に接続すると ORA-21561 で失敗する

事象

sqlplus から Oracle Database に接続すると ORA-21561 で失敗する。

% sqlplus awsuser/******@******.******.ap-northeast-1.rds.amazonaws.com:1521/ORCL

SQL*Plus: Release 12.1.0.2.0 Production on Mon Sep 18 22:37:57 2017

Copyright (c) 1982, 2016, Oracle.  All rights reserved.

ERROR:
ORA-21561: OID generation failed

ORA-21561: OID生成に失敗しました

原因: 渡されたハンドルが有効でない可能性があります。

処置: env、svcハンドルの妥当性を確認してください。

ORA-19999からORA-24279

原因

  • /etc/hosts にホスト名のマッピングがない、もしくは間違っている。

Incorrect /etc/hosts mapping for the client machine or no mapping at all.

Sfaturi Oracle / Tips and tricks OracleDBA: ORA-21561 : OID generation failed

対処

  • ホスト名を確認する
% uname -n
******.***.foo.com
  • /etc/hosts に追記する
% sudo vi /etc/hosts
127.0.0.1	localhost ******.***.foo.com

環境


参考

Mac OS X に Oracle Instant Client をインストールする

ダウンロード


インストール

% unzip instantclient-basic-macos.x64-12.1.0.2.0.zip
Archive:  instantclient-basic-macos.x64-12.1.0.2.0.zip
  inflating: instantclient_12_1/BASIC_README
  inflating: instantclient_12_1/adrci
  inflating: instantclient_12_1/genezi
  inflating: instantclient_12_1/libclntsh.dylib.12.1
  inflating: instantclient_12_1/libclntshcore.dylib.12.1
  inflating: instantclient_12_1/libnnz12.dylib
  inflating: instantclient_12_1/libocci.dylib.12.1
  inflating: instantclient_12_1/libociei.dylib
  inflating: instantclient_12_1/libocijdbc12.dylib
  inflating: instantclient_12_1/libons.dylib
  inflating: instantclient_12_1/liboramysql12.dylib
  inflating: instantclient_12_1/ojdbc6.jar
  inflating: instantclient_12_1/ojdbc7.jar
  inflating: instantclient_12_1/uidrvci
  inflating: instantclient_12_1/xstreams.jar
% unzip instantclient-sqlplus-macos.x64-12.1.0.2.0.zip
Archive:  instantclient-sqlplus-macos.x64-12.1.0.2.0.zip
  inflating: instantclient_12_1/SQLPLUS_README
  inflating: instantclient_12_1/glogin.sql
  inflating: instantclient_12_1/libsqlplus.dylib
  inflating: instantclient_12_1/libsqlplusic.dylib
  inflating: instantclient_12_1/sqlplus
  • 移動する
% sudo mkdir -p /opt/oracle
% sudo mv instantclient_12_1 /opt/oracle
  • パスを通す
% vi .zshrc.local
export PATH=$PATH:/opt/oracle/instantclient_12_1

接続する

$ sqlplus awsuser/******@******.******.ap-northeast-1.rds.amazonaws.com:1521/ORCL

2017-09-10

Oracle Database の PL/SQL を MySQL にどう移行するか

はじめに

Oracle Database の PL/SQLMySQL への移行方法を説明します(MySQL 5.0 からストアドプロシージャに対応している)。

AWS Schema Conversion Tool (SCT) という GUI デスクトップアプリケーション(Windwos/Mac OS X/Linux版)をインストールし、移行元の Oracle Database に接続して自動的にPL/SQLMySQL のルーチンに変換することができます。

SCT による変換方法は Oracle Database を Amazon Aurora に移行する方法 | Amazon Web Services ブログ をご覧ください。


移行先として適切なサービスを選ぶ

本題に入る前に Oracle Database からの移行先として MySQLPostgreSQL、Redshift のどれが適切か説明します。

経験上、エンタープライズOracle Database を使っている場合は PostgreSQL が向いているケースが多いです。アクセスブロック数が少ないSQLのみで結合もネステッドループのみで問題ないシステムは MySQL が向いています。Exadata で OLTP(トランザクション) とOLAP(分析)を共存させている場合は PostgreSQL で OLTP、Redshift で OLAP(分析)という使い分けをオススメします。

MySQL が向いているケース
  • OLTP でシンプルでアクセスブロック数が少ないSQLが大半。
  • 結合はネステッドループのみで問題ない程度の軽い SQL のみ。
  • さらに結合も必要なく、キーのみにでアクセスするケースでは DynamoDB が向いています。
PostgreSQL が向いているケース
  • OLTP でも結合対象行数を絞れず HASH JOIN が必要な重いSQLが多い。
  • エンタープライズOracle Database を使っているシステムはこのケースが一番多い印象。
Redshift が向いているケース
  • Exadata で集計処理を投げていて Smart Scan を享受しているようなケースでは Redshift が向いている。
  • Exadata で OTLP(トランザクション処理)と分析の両方の用途で使っている場合は、OLTP は RDS で、分析は Redshift というように使い分けるアーキテクチャにする。

Oracle Database と MySQL のプロシージャ・ファンクションの構文の違い

SCT でプロシージャを変換した例

aws-database-migration-samples/generate_tickets.pls at master ? awslabs/aws-database-migration-samples ? GitHub を変換した例です。

  • Oracle Database(変換前)
procedure generate_tickets(P_event_id IN NUMBER) as
  CURSOR event_cur(P_ID NUMBER) IS
  SELECT id,location_id
  FROM   sporting_event
  WHERE  ID = P_ID;

  standard_price NUMBER(6,2);

BEGIN
  standard_price := DBMS_RANDOM.VALUE(30,50);

  FOR event_rec IN event_cur(P_event_id) LOOP
    INSERT /*+ APPEND */ INTO sporting_event_ticket(id,sporting_event_id,sport_location_id,seat_level,seat_section,seat_row,seat,ticket_price)
    SELECT sporting_event_ticket_seq.nextval
      ,sporting_event.id
      ,seat.sport_location_id
      ,seat.seat_level
      ,seat.seat_section
      ,seat.seat_row
      ,seat.seat
      ,(CASE
         WHEN seat.seat_type = 'luxury' THEN 3*standard_price
         WHEN seat.seat_type = 'premium' THEN 2*standard_price
         WHEN seat.seat_type = 'standard' THEN standard_price
         WHEN seat.seat_type = 'sub-standard' THEN 0.8*standard_price
         WHEN seat.seat_type = 'obstructed' THEN 0.5*standard_price
         WHEN seat.seat_type = 'standing' THEN 0.5*standard_price
      END ) ticket_price
    FROM sporting_event
       ,seat
    WHERE sporting_event.location_id = seat.sport_location_id
    AND   sporting_event.id = event_rec.id;
  END LOOP;
END;
  • MySQL(変換後)
    • コメントが入っている箇所は Oracle Database の構文に相当するものが MySQL になかった箇所で、この部分は自分でワークアラウンドを記述する必要があります。
CREATE PROCEDURE DMS_SAMPLE.GENERATE_TICKETS(IN par_P_EVENT_ID DOUBLE)
BEGIN
    DECLARE var$ID DOUBLE;
    DECLARE var$LOCATION_ID DOUBLE;
    DECLARE par_P_ID DOUBLE;
    DECLARE var_standard_price DECIMAL (6, 2);
    DECLARE done INT DEFAULT FALSE;
    DECLARE event_cur CURSOR FOR SELECT
        ID,a
        FROM SPORTING_EVENT
        WHERE ID = par_P_ID;
    DECLARE CONTINUE HANDLER FOR NOT FOUND
        SET done := TRUE
    /*
    [340 - Severity CRITICAL - MySQL doesn't support the SYS.DBMS_RANDOM.VALUE(NUMBER,NUMBER) function. Create a user-defined function.]
    standard_price := DBMS_RANDOM.VALUE(30,50)
    */;
    SET par_P_ID := par_P_event_id;
    OPEN event_cur;

    read_label:
    LOOP
        FETCH event_cur INTO var$ID, var$LOCATION_ID;

        IF done THEN
            LEAVE read_label;
        END IF;
        INSERT INTO SPORTING_EVENT_TICKET
            (ID, SPORTING_EVENT_ID, SPORT_LOCATION_ID, SEAT_LEVEL, SEAT_SECTION, SEAT_ROW, SEAT, TICKET_PRICE)
            SELECT
                aws_oracle_ext.sequence$nextval('SPORTING_EVENT_TICKET_SEQ', 'DMS_SAMPLE'), SPORTING_EVENT.ID, SEAT.SPORT_LOCATION_ID, SEAT.SEAT_LEVEL, SEAT.SEAT_SECTION, SEAT.SEAT_ROW, SEAT.SEAT, (CASE WHEN SEAT.SEAT_TYPE = 'luxury' THEN 3 * var_standard_price WHEN SEAT.SEAT_TYPE = 'premium' THEN 2 * var_standard_price WHEN SEAT.SEAT_TYPE = 'standard' THEN var_standard_price WHEN SEAT.SEAT_TYPE = 'sub-standard' THEN 0.8 * var_standard_price WHEN SEAT.SEAT_TYPE = 'obstructed' THEN 0.5 * var_standard_price WHEN SEAT.SEAT_TYPE = 'standing' THEN 0.5 * var_standard_price END) AS ticket_price
                FROM SPORTING_EVENT, SEAT
                WHERE SPORTING_EVENT.LOCATION_ID = SEAT.SPORT_LOCATION_ID AND SPORTING_EVENT.ID = var$ID;
    END LOOP;
    CLOSE event_cur;
END;


比較

CREATE PROCEDURE Statement

#OracleMySQL
1CREATE OR REPLACE PROCEDURE DROP PROCEDURE IF EXISTS and CREATE PROCEDURE
2param IN / OUT / IN OUT datatype Parameter definition IN / OUT / INOUT param datatype(length)
3IS / AS Removed
4Variable declaration is before BEGIN Variable declaration is after BEGIN
5END sp_name END

CREATE FUNCTION Statement

  • Converting user-defined functions from Oracle to MySQL:
#Oracle MySQL
1CREATE OR REPLACE FUNCTION DROP FUNCTION IF EXISTS and CREATE FUNCTION
2param IN / OUT / IN OUT datatype Parameter definition param datatype(length)
3RETURN datatype Return value RETURNS datatype(length)
4IS / AS Removed
5Variable declaration is before BEGIN Variable declaration is after BEGIN
6END func_name END

PL/SQL Statements

#OracleMySQL
1variable datatype := value Variable declaration DECLARE variable datatype DEFAULT value
2variable := value Assignment statement SET variable = value
3CURSOR cur (params) IS SELECT Cursor declaration DECLARE cur CURSOR FOR SELECT
4Variable and cursor declarations can be mixed in any order Variable declarations must be before cursor and handlers
5FOR rec IN cursor LOOP Cursor loop OPEN cursor WHILE-FETCH-CLOSE
6IF THEN ELSIF ELSE END IF IF statement IF THEN ELSEIF ELSE END IF
7WHILE condition LOOP sql END LOOP A loop statement WHILE condition DO sql END WHILE
8EXIT WHEN condition Exit from a loop IF condition THEN LEAVE label END IF
  • EXCEPTION block:
#Oracle MySQL
1BEGIN stmts EXCEPTION … END Exception block structure BEGIN DECLARE HANDLER … stmts END
2WHEN DUP_VAL_ON_INDEX Duplicate key DECLARE EXIT HANDLER FOR SQLSTATE '23000'
3WHEN NO_DATA_FOUND No rows found DECLARE EXIT HANDLER FOR NOT FOUND
4WHEN OTHERS All exceptions DECLARE EXIT HANDLER FOR SQLEXCEPTION
http://www.sqlines.com/oracle-to-mysql#plsql-statements
  • パッケージ変数MySQL ではセション変数(@)で代用できる。
  • 結果セットの返却は MySQL では SELECT 文を書くだけ。
  • %TYPE および %ROWTYPE データ型定義は MySQL にはない。

SCTを使った変換手順例

$ git clone https://github.com/awslabs/aws-database-migration-samples.git
$ sudo rpm -ivh oracle-instantclient12.2-basic-12.2.0.1.0-1.x86_64.rpm
$ sudo rpm -ivh oracle-instantclient12.2-sqlplus-12.2.0.1.0-1.x86_64.rpm
$ rpm -ql oracle-instantclient12.2-sqlplus-12.2.0.1.0-1.x86_64
/usr/bin/sqlplus64
/usr/lib/oracle/12.2/client64/bin/sqlplus
/usr/lib/oracle/12.2/client64/lib/glogin.sql
/usr/lib/oracle/12.2/client64/lib/libsqlplus.so
/usr/lib/oracle/12.2/client64/lib/libsqlplusic.so
$ rpm -ql oracle-instantclient12.2-basic-12.2.0.1.0-1.x86_64
/usr/lib/oracle/12.2/client64/bin/adrci
/usr/lib/oracle/12.2/client64/bin/genezi
/usr/lib/oracle/12.2/client64/lib/libclntsh.so.12.1
/usr/lib/oracle/12.2/client64/lib/libclntshcore.so.12.1
/usr/lib/oracle/12.2/client64/lib/libipc1.so
/usr/lib/oracle/12.2/client64/lib/libmql1.so
/usr/lib/oracle/12.2/client64/lib/libnnz12.so
/usr/lib/oracle/12.2/client64/lib/libocci.so.12.1
/usr/lib/oracle/12.2/client64/lib/libociei.so
/usr/lib/oracle/12.2/client64/lib/libocijdbc12.so
/usr/lib/oracle/12.2/client64/lib/libons.so
/usr/lib/oracle/12.2/client64/lib/liboramysql12.so
/usr/lib/oracle/12.2/client64/lib/ojdbc8.jar
/usr/lib/oracle/12.2/client64/lib/xstreams.jar
$ vi ~.bashrc
export PATH=$PATH:/usr/lib/oracle/12.2/client64/bin
export NLS_LANG=American_America.UTF8
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/oracle/12.2/client64/lib
$ sudo yum -y install git
$ git clone https://github.com/awslabs/aws-database-migration-samples.git
$ cd aws-database-migration-samples/oracle/sampledb/v1
$ sqlplus awsuser/******@******.******.ap-northeast-1.rds.amazonaws.com:1521/ORCL
SQL> install-rds.sql
  • SCT でソースとターゲットを指定して、変換する。

補足


参考

2017-09-04

pgbench で RDS PostgreSQL のマスターに負荷をかけてリードレプリカのレプリケーションラグを計測する

pgbench とは

pgbenchとは

pgbenchはPostgreSQLに同梱されているシンプルなベンチマークツールです。最初のバージョンは筆者により作成され、日本のPostgreSQLメーリングリストで1999年に公開されました。その後pgbenchはcontribという付属追加プログラムとして、PostgreSQLのソースコードとともに配布されるようになりました。どのバージョンでPostgreSQLに取り込まれたのかはPostgreSQL付属のドキュメント(HISTORY)には書かれていないので定かではないのですが、コミットログを見ると、おそらく2000年にリリースされたPostgreSQL 7.0で導入されたと思われます。その後数多くの改良がたくさんの人によって行われ、現在に至っています。

(中略)

pgbenchが標準で実行するトランザクションはTPC-Bを想定しているものとはいえ、実際に使ってみると不都合なこともあります。特に問題なのは、上記ステップ4で、pgbench_branchesの行数がスケーリングファクタと同じ(つまりデフォルトでは10)しかないため、同時接続数が10を超えるとロック競合が発生して性能が出なくなるということです。現実のシステムではこのような設計は普通は行わないので、実際のシステムでの性能を推し量るという、ベンチマーク本来の目的にはあまりそぐわないことになります。

そこでpgbenchでは3と4の処理を省略したトランザクションのモードを用意しており、pgbenchを実行するときに"-N"を付けることによって実行できます。Webシステムのように、多数の同時接続を想定している場合は、こちらを使うことをお勧めします。

pgbenchの使いこなし | Let's Postgres

準備

RDS PostgreSQL のマスターとリードレプリカを作成する
EC2 から RDS PostgreSQL に接続してセットアップする
$ sudo yum -y install postgresql
$ sudo yum -y install postgresql-contrib
$ pgbench -i -s 1000 -U awsuser -h ******.******.ap-northeast-1.rds.amazonaws.com -d mydb
  • テーブルを確認する
$ psql "host=******.*******.ap-northeast-1.rds.amazonaws.com user=awsuser dbname=mydb port=5432"
Password:
mydb=> select * from pg_tables where schemaname='public';
 schemaname |    tablename     | tableowner | tablespace | hasindexes | hasrules | hastriggers | rowsecurity
------------+------------------+------------+------------+------------+----------+-------------+-------------
 public     | pgbench_branches | awsuser    |            | t          | f        | f           | f
 public     | pgbench_tellers  | awsuser    |            | t          | f        | f           | f
 public     | pgbench_accounts | awsuser    |            | t          | f        | f           | f
 public     | pgbench_history  | awsuser    |            | f          | f        | f           | f
(4 rows)

ベンチマーク実施

  • マスターにトランザクションを発行して負荷をかける
    • N: pgbench_tellersとpgbench_branchesを更新しない。マスターでロック競合がボトルネックになるとトランザクションのスループットが伸びずレプリケーション意外のボトルネックで頭打ちになる可能性があるため。
    • r: ステートメント毎の平均レイテンシをレポートする
    • c: クライアント
    • j: ワーカースレッド数
    • t: トランザクション
    • U: DBユーザー名
    • d: データベース
$ pgbench -r -c 10 -j 10 -t 10000 -U awsuser -h ******.******.ap-northeast-1.rds.amazonaws.com -d mydb 

(中略)

transaction type: TPC-B (sort of)
scaling factor: 1000
query mode: simple
number of clients: 10
number of threads: 10
number of transactions per client: 10000
number of transactions actually processed: 100000/100000
tps = ***.****** (including connections establishing)
tps = ***.****** (excluding connections establishing)
statement latencies in milliseconds:

(中略)

	*.********	BEGIN;
	*.********	UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
	*.********	SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
	*.********	UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
	*.********	UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
	*.********	INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
	*.********	END;
  • リードレプリカでレプリケーションラグを確認する
    • マネジメントコンソールの「レプリケーションの詳細」でも確認できる
    • 以下の単位は秒
$ psql "host=******.******.ap-southeast-1.rds.amazonaws.com user=awsuser dbname=mydb port=5432"
Password:

mydb=> SELECT EXTRACT(EPOCH FROM (now() - pg_last_xact_replay_timestamp()))::INT;

 date_part
-----------
       0
(1 row)

mydb=> SELECT EXTRACT(EPOCH FROM (now() - pg_last_xact_replay_timestamp()))::INT;
 date_part
-----------
       0
(1 row)

参考

Amazon Redshift announces Federated Authentication with Single Sign-On

Posted On: Aug 11, 2017

You can now use the new Amazon Redshift database authentication to simplify the credential management of database users. You can configure Amazon Redshift to automatically generate temporary database credentials based on permissions granted through an AWS IAM policy. You can leverage your corporate directory and third-party SAML-2.0 identity provider, such as ADFS, PingFederate and Okta, to enable your users to easily access their Amazon Redshift clusters using their corporate user names, without managing database users and passwords. Furthermore, database users are automatically created at their first login based on their corporate privileges. The new Amazon Redshift ODBC and JDBC drivers support Windows Integrated Authentication for a simplified client experience. This feature is supported starting with Amazon Redshift ODBC driver version 1.3.6.1000 and JDBC driver version 1.2.7.1003. For more information, see Using IAM Authentication to Generate Database User Credentials in the Amazon Redshift Database Developer Guide.

Amazon Redshift Federated Authentication with Single Sign-On is available in US East (N. Virginia), US East (Ohio), US West (N. California), US West (Oregon), EU (Frankfurt), EU (Ireland), EU (London), Asia Pacific (Singapore), Asia Pacific (Tokyo), Asia Pacific (Sydney), Asia Pacific (Seoul), Asia Pacific (Mumbai), Canada (Central), and South America (São Paulo) Regions.

Amazon Redshift announces Federated Authentication with Single Sign-On


JDBC/ODBC接続設定

JDBC接続文字列の例

Add JDBC options that the JDBC driver uses to call the GetClusterCredentials API action. Don't include these options if you call the GetClusterCredentials API action programmatically. For more details, see Configure a JDBC or ODBC Connection to Use IAM Credentials.

The following example includes the JDBC GetClusterCredentials options.

jdbc:redshift:iam://examplecluster:us-west-2/dev?Profile=user2&DbUser=newuser&AutoCreate=true&DbGroups=group1,group2
ステップ 5: IAM 認証情報を使用するように JDBC または ODBC 接続を設定する - Amazon Redshift

"Profile=user2" は名前付きプロファイルを指定している。

Using a Configuration Profile

You can supply the IAM credentials options and GetClusterCredentials options as settings in named profiles in your AWS configuration file. Provide the profile name by using the Profile JDBC option.

The configuration is stored in a file named config in a folder named .aws in your home directory. Home directory location varies but can be referred to using the environment variables %UserProfile% in Windows and $HOME or ~ (tilde) in Unix-like systems.

(中略)

The following example shows a configuration file with three profiles. The plug-in-creds example includes the optional DbUser, AutoCreate, and DbGroups options.

[default]
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

[user2]
aws_access_key_id=AKIAI44QH8DHBEXAMPLE
aws_secret_access_key=je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY
session_token=AQoDYXdzEPT//////////wEXAMPLEtc764bNrC9SAPBSM22wDOk4x4HIZ8j4FZTwdQWLWsKWHGBuFqwAeMicRXmxfpSPfIeoIYRqTflfKD8YUuwthAx7mSEI/qkPpKPi/kMcGd
QrmGdeehM4IC1NtBmUpp2wUE8phUZampKsburEDy0KPkyQDYwT7WZ0wq5VSXDvp75YU
9HFvlRd8Tx6q6fE8YQcHNVXAkiY9q6d+xo0rKwT38xVqr7ZD0u0iPPkUL64lIZbqBAz
+scqKmlzm8FDrypNC9Yjc8fPOLn9FX9KSYvKTr4rvx3iSIlTJabIQwj2ICCR/oLxBA==

[plug-in-creds]
plugin_name=com.amazon.redshift.plugin.AdfsCredentialsProvider
idp_host=demo.example.com
idp_port=443
preferred_role=arn:aws:iam::1234567:role/ADFS-Dev
user=example\user
password=Password1234 

To use the credentials for the user2 example, specify Profile=user2 in the JDBC URL. To use the credentials for the plug-in creds example, specify Profile=plug-in-creds in the JDBC URL.

For more information, see Named Profiles in the AWS Command Line Interface User Guide.

IAM 認証情報の提供オプション - Amazon Redshift

AWS CLI は config と認証情報ファイルに保存された 名前付きプロファイルをサポートしています。追加のプロファイルを設定するには、--profile オプションで aws configure を使用するか、または、config と認証情報ファイルへエントリを追加します。

2 つのプロファイルのある認証情報ファイルの例を以下に示します。

  • ~/.aws/credentials
[default]
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

[user2]
aws_access_key_id=AKIAI44QH8DHBEXAMPLE
aws_secret_access_key=je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY
各プロファイルは異なる認証情報 (2 人の異なる IAM ユーザーのもの) を使用します。別のリージョンおよび出力形式を使用することもできます。
  • ~/.aws/config
[default]
region=us-west-2
output=json

[profile user2]
region=us-east-1
output=text
  • 重要
    • AWS 認証情報ファイルは、CLI ファイルの名前付きプロファイルとは別の命名形式を使用します。AWS 認証情報ファイルで名前付きプロファイルを設定するときは、「profile」プレフィックスは含めないでください。
名前付きプロファイル - AWS Command Line Interface

AD FS の場合

Identity Provider: AD FS

For Windows Integrated Authentication with AD FS, leave User and Password empty.Optionally, provide details for options that the ODBC driver uses to call the GetClusterCredentials API action.

  • DbUser
  • User AutoCreate
  • DbGroups

For more information, see JDBC and ODBC Options for Creating Database User Credentials.

Provide IdP details.

  • IdP Host
    • The name of the corporate identity provider host. This name should not include any slashes ( / ).
  • IdP Port (optional)
    • The port used by identity provider. The default is 443.
  • Preferred Role
    • A role Amazon Resource Name (ARN) from the AttributeValue elements for the Role attribute in the SAML assertion. Work with your IdP administrator to find the appropriate value for the preferred role. For more information, see Configure SAML Assertions for Your IdP.

f:id:yohei-a:20170904085944p:image

ステップ 5: IAM 認証情報を使用するように JDBC または ODBC 接続を設定する - Amazon Redshift

参考

2017-06-29

Parquet-tools で Parquet ファイルのメタデータや中身を見る

Apache Parquet とは

2010年に Google が発表した Dremel 論文の "record shredding and assembly algorithm" の内容をベースに Twitter と Cloudera が開発した列指向データ構造で、現在は Apache プロジェクトになっている。

詳しくは Retty 林田さんのこちらの記事 参照。

Parquet はバイナリフォーマットで Parquet-tools でメタデータやデータを見ることができる。


環境


インストール手順

Maven のインストール
$ brew  install maven32
thrift のインストール
$ brew install thrift
parquet-tools のインストール
  • github からソースコードを取得する。
$ git clone https://github.com/Parquet/parquet-mr.git 
$ cd parquet-mr/parquet-tools/ 
$ vi pom.xml
    <groupId>com.twitter</groupId>
    <artifactId>parquet</artifactId>
    <relativePath>../pom.xml</relativePath>
    
    <version>1.6.0</version>
  • ビルドする
$ mvn clean package -Plocal 

使ってみる

  • メタデータを確認する。
$ java -jar parquet-tools-1.6.0.jar meta sample.snappy.parquet
file:                    file:/Users/yoheia/sample.snappy.parquet
creator:                 parquet-mr
extra:                   org.apache.spark.sql.parquet.row.metadata = {"type":"struct","fields":[{"name":"request_timestamp","type":"string","nullable":true,"metadata":{}},{"name":"elb_name","type":"string","nullable":true,"metadata":{}},{"name":"request_ip","type":"string","nullable":true,"metadata":{}},{"name":"request_port","type":"integer","nullable":true,"metadata":{}},{"name":"backend_ip","type":"string","nullable":true,"metadata":{}},{"name":"backend_port","type":"integer","nullable":true,"metadata":{}},{"name":"request_processing_time","type":"double","nullable":true,"metadata":{}},{"name":"backend_processing_time","type":"double","nullable":true,"metadata":{}},{"name":"client_response_time","type":"double","nullable":true,"metadata":{}},{"name":"elb_response_code","type":"string","nullable":true,"metadata":{}},{"name":"backend_response_code","type":"string","nullable":true,"metadata":{}},{"name":"received_bytes","type":"long","nullable":true,"metadata":{}},{"name":"sent_bytes","type":"long","nullable":true,"metadata":{}},{"name":"request_verb","type":"string","nullable":true,"metadata":{}},{"name":"url","type":"string","nullable":true,"metadata":{}},{"name":"protocol","type":"string","nullable":true,"metadata":{}},{"name":"user_agent","type":"string","nullable":true,"metadata":{}},{"name":"ssl_cipher","type":"string","nullable":true,"metadata":{}},{"name":"ssl_protocol","type":"string","nullable":true,"metadata":{}}]}

file schema:             spark_schema
--------------------------------------------------------------------------------
request_timestamp:       OPTIONAL BINARY O:UTF8 R:0 D:1
elb_name:                OPTIONAL BINARY O:UTF8 R:0 D:1
request_ip:              OPTIONAL BINARY O:UTF8 R:0 D:1
request_port:            OPTIONAL INT32 R:0 D:1
backend_ip:              OPTIONAL BINARY O:UTF8 R:0 D:1
backend_port:            OPTIONAL INT32 R:0 D:1
request_processing_time: OPTIONAL DOUBLE R:0 D:1
backend_processing_time: OPTIONAL DOUBLE R:0 D:1
client_response_time:    OPTIONAL DOUBLE R:0 D:1
elb_response_code:       OPTIONAL BINARY O:UTF8 R:0 D:1
backend_response_code:   OPTIONAL BINARY O:UTF8 R:0 D:1
received_bytes:          OPTIONAL INT64 R:0 D:1
sent_bytes:              OPTIONAL INT64 R:0 D:1
request_verb:            OPTIONAL BINARY O:UTF8 R:0 D:1
url:                     OPTIONAL BINARY O:UTF8 R:0 D:1
protocol:                OPTIONAL BINARY O:UTF8 R:0 D:1
user_agent:              OPTIONAL BINARY O:UTF8 R:0 D:1
ssl_cipher:              OPTIONAL BINARY O:UTF8 R:0 D:1
ssl_protocol:            OPTIONAL BINARY O:UTF8 R:0 D:1

...
$ java -jar parquet-tools-1.6.0.jar schema sample.snappy.parquet
message spark_schema {
  optional binary request_timestamp (UTF8);
  optional binary elb_name (UTF8);
  optional binary request_ip (UTF8);
  optional int32 request_port;
  optional binary backend_ip (UTF8);
  optional int32 backend_port;
  optional double request_processing_time;
  optional double backend_processing_time;
  optional double client_response_time;
  optional binary elb_response_code (UTF8);
  optional binary backend_response_code (UTF8);
  optional int64 received_bytes;
  optional int64 sent_bytes;
  optional binary request_verb (UTF8);
  optional binary url (UTF8);
  optional binary protocol (UTF8);
  optional binary user_agent (UTF8);
  optional binary ssl_cipher (UTF8);
  optional binary ssl_protocol (UTF8);
}

...
  • データの中身を参照する(先頭だけ)。
$ java -jar parquet-tools-1.6.0.jar head -n 1 sample.snappy.parquet
request_timestamp = 2015-01-09T03:10:16.796840Z
elb_name = elb_demo_008
request_ip = ...
request_port = 6266
backend_ip = 172.30.55.212
backend_port = 80
request_processing_time = 6.05E-4
backend_processing_time = 0.001817
client_response_time = 3.56E-4
elb_response_code = 200
backend_response_code = 200
received_bytes = 0
sent_bytes = 2452
request_verb = GET
url = http://www.example.com/articles/407
protocol = HTTP/1.1
user_agent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36"
ssl_cipher = -
ssl_protocol = -
  • データの中身を参照する(全て)。
$ java -jar parquet-tools-1.6.0.jar cat sample.parquet 
(出力結果は割愛)

参考

2017-05-17

S3で jQuery を使って SSI 的なことをする

S3 で Server Side Include (SSI)的なことを jQuery でやってみた(Client Side Include)。


結果

  • 作成したバケットの [プロパティ]-[Static website hosting] を選択し、
  • [エンドポイント]の URL にブラウザでアクセスしてみると無事成功

f:id:yohei-a:20170517142335p:image


手順

  • S3 にバケットを作成する
  • 作成したバケットの [プロパティ]-[Static website hosting]で以下の通り入力して保存
    • 「このバケットを使用してウェブサイトをホストする」を選択
    • インデックスドキュメント: index.html
    • エラードキュメント: error.html
  • 作成したバケットの[アクセス権限]-[バケットポリシー]-[バケットポリシーエディター ]に以下を入力して保存
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::<バケット名>/*"
            ]
        }
    ]
    • 作成したバケットの[オブジェクト]で index.html と ssi.html をアップロードする。

ファイル

  • index.html
<html> 
  <head> 
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script> 
    $(function(){
      $("#includedContent").load("ssi.html"); 
    });
    </script> 
  </head> 

  <body> 
     <div id="includedContent"></div>
  </body> 
</html>
    • ssi.html
<font color="red" size="7">This is ssi content.</font>

参考