Amazon Aurora
AWS製クラウドネイティブリレーショナルデータベース。MySQL・PostgreSQL互換でクラウド最適化。自動スケーリング・高可用性を提供。
データベースサーバー
Amazon Aurora
概要
Amazon Auroraは、AWSが提供するクラウドネイティブな完全管理型リレーショナルデータベースエンジンです。MySQLとPostgreSQLとの完全な互換性を保ちながら、標準的なMySQLの5倍、PostgreSQLの3倍のパフォーマンスを実現しています。クラウドファーストの設計により、99.99%の高可用性、自動的なスケーリング、障害時の自動復旧機能を提供し、エンタープライズレベルのワークロードから急成長するアプリケーションまで幅広く対応します。2025年には新たにAurora DSQLが一般提供され、分散SQL市場のリーダーとしての地位を確立しています。
詳細
Amazon Aurora 2025年版は、分散データベースの新時代を切り開く革新的な機能群が大幅に強化されています。特に注目すべきはAurora DSQLの一般提供開始で、PostgreSQL互換のサーバーレス分散データベースとして、アクティブ-アクティブ高可用性とマルチリージョン強整合性を実現しています。PostgreSQL機能強化では、pgvectorを使用したベクター検索が最大9倍高速化され、Aurora PostgreSQL Limitless Databaseによる水平スケーリングが自動化されました。ストレージは最大128TiBまで自動拡張し、Aurora Parallel Queryにより分析クエリの性能が最大100倍向上、Aurora Serverlessによるオンデマンド自動スケーリングが完全自動化されています。
主な特徴
- クラウドネイティブ設計: MySQL/PostgreSQLの5倍/3倍のパフォーマンス
- 完全管理型: サーバー管理、パッチ適用、高可用性設定が不要
- 自動スケーリング: ワークロードに応じて自動的にキャパシティを調整
- 高可用性: 99.999%のマルチリージョン可用性設計
- 分散機能: Aurora DSQLによる分散SQLデータベース
- 互換性: 既存のMySQL/PostgreSQLアプリケーションとツールが変更なしで動作
メリット・デメリット
メリット
- AWS環境における圧倒的な統合性と運用管理の完全自動化
- 標準のMySQL/PostgreSQLを大幅に上回る性能とスケーラビリティ
- 99.99%の高可用性とマルチAZ、グローバルレプリケーション対応
- Aurora Serverlessによる使用量に応じた完全な従量課金制
- エンタープライズ級のセキュリティとバックアップ・復旧機能
- 既存アプリケーションの変更なしでの移行が可能
デメリット
- AWS環境への強力なロックインとベンダー依存
- MySQLやPostgreSQLと比較して高い運用コスト
- オンプレミス環境での利用不可
- 一部の高度なPostgreSQL機能やMySQL拡張の制限
- Aurora DSQLは比較的新しいサービスで実績が限定的
- 大規模なデータベースでは予想以上にコストが増大する可能性
参考ページ
書き方の例
Aurora MySQL基本セットアップ
# AWS CLIを使用したAurora MySQLクラスター作成
aws rds create-db-cluster \
--db-cluster-identifier myapp-aurora-cluster \
--engine aurora-mysql \
--engine-version 8.0.mysql_aurora.3.02.0 \
--master-username admin \
--master-user-password MySecurePassword123 \
--vpc-security-group-ids sg-12345678 \
--db-subnet-group-name myapp-subnet-group \
--backup-retention-period 7 \
--preferred-backup-window 03:00-04:00 \
--preferred-maintenance-window sun:04:00-sun:05:00 \
--enable-cloudwatch-logs-exports error,general,slow-query \
--deletion-protection
# Aurora MySQLインスタンス作成
aws rds create-db-instance \
--db-instance-identifier myapp-aurora-instance-1 \
--db-cluster-identifier myapp-aurora-cluster \
--db-instance-class db.r6g.xlarge \
--engine aurora-mysql \
--auto-minor-version-upgrade \
--monitoring-interval 60 \
--monitoring-role-arn arn:aws:iam::123456789012:role/rds-monitoring-role
# Aurora PostgreSQL クラスター作成
aws rds create-db-cluster \
--db-cluster-identifier myapp-aurora-pg-cluster \
--engine aurora-postgresql \
--engine-version 14.9 \
--master-username postgres \
--master-user-password MySecurePassword123 \
--vpc-security-group-ids sg-12345678 \
--db-subnet-group-name myapp-subnet-group \
--backup-retention-period 7 \
--enable-cloudwatch-logs-exports postgresql
# クラスター情報確認
aws rds describe-db-clusters --db-cluster-identifier myapp-aurora-cluster
# エンドポイント確認
aws rds describe-db-cluster-endpoints --db-cluster-identifier myapp-aurora-cluster
Aurora MySQL接続とデータベース操作
-- Aurora MySQL接続(mysql commandline client)
mysql -h myapp-aurora-cluster.cluster-123456789012.us-east-1.rds.amazonaws.com \
-u admin -p myapp_database
-- データベース作成
CREATE DATABASE myapp_production
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
USE myapp_production;
-- テーブル作成(InnoDB Engine、Aurora最適化)
CREATE TABLE users (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
first_name VARCHAR(50),
last_name VARCHAR(50),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_users_email (email),
INDEX idx_users_created_at (created_at)
) ENGINE=InnoDB;
-- リードレプリカを活用したクエリ
-- ライターエンドポイント(書き込み用)
INSERT INTO users (username, email, first_name, last_name) VALUES
('john_doe', '[email protected]', 'John', 'Doe'),
('jane_smith', '[email protected]', 'Jane', 'Smith'),
('bob_wilson', '[email protected]', 'Bob', 'Wilson');
-- リーダーエンドポイント(読み取り用)
SELECT id, username, email, CONCAT(first_name, ' ', last_name) as full_name
FROM users
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 1 DAY);
-- Aurora MySQL固有機能:クエリ実行プラン確認
EXPLAIN FORMAT=JSON
SELECT u.username, u.email
FROM users u
WHERE u.created_at >= '2024-01-01'
ORDER BY u.created_at DESC
LIMIT 100;
-- Aurora Parallel Query(大規模テーブル向け)
-- (注:自動的に適用されるため、特別な構文は不要)
SELECT DATE(created_at) as signup_date, COUNT(*) as signups
FROM users
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 90 DAY)
GROUP BY DATE(created_at)
ORDER BY signup_date;
Aurora PostgreSQL高度な機能
-- Aurora PostgreSQL接続
psql -h myapp-aurora-pg-cluster.cluster-123456789012.us-east-1.rds.amazonaws.com \
-U postgres -d myapp_database
-- 拡張機能の有効化
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
CREATE EXTENSION IF NOT EXISTS "pg_stat_statements";
CREATE EXTENSION IF NOT EXISTS "pg_trgm"; -- 類似検索用
CREATE EXTENSION IF NOT EXISTS "btree_gist"; -- 高度なインデックス用
-- JSON/JSONB機能を活用したテーブル
CREATE TABLE products (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name VARCHAR(255) NOT NULL,
description TEXT,
specifications JSONB,
tags TEXT[],
price DECIMAL(10, 2),
inventory_count INTEGER DEFAULT 0,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
-- JSONBインデックス
GIN INDEX ON specifications,
GIN INDEX ON tags
);
-- JSONB データ挿入
INSERT INTO products (name, description, specifications, tags, price) VALUES
(
'Gaming Laptop',
'High-performance gaming laptop',
'{
"cpu": "Intel Core i7-12700H",
"gpu": "NVIDIA RTX 3070",
"memory": "32GB DDR4",
"storage": "1TB NVMe SSD",
"display": {
"size": 15.6,
"resolution": "1920x1080",
"refresh_rate": 144
}
}',
ARRAY['gaming', 'laptop', 'nvidia', 'intel'],
1299.99
),
(
'Workstation Desktop',
'Professional workstation for content creation',
'{
"cpu": "AMD Ryzen 9 5950X",
"gpu": "NVIDIA RTX 4080",
"memory": "64GB DDR4",
"storage": "2TB NVMe SSD",
"cooling": "AIO Liquid Cooling"
}',
ARRAY['workstation', 'desktop', 'amd', 'content-creation'],
2499.99
);
-- JSONB クエリ例
-- 特定のGPUを持つ製品検索
SELECT name, specifications->>'gpu' as gpu, price
FROM products
WHERE specifications->>'gpu' LIKE '%RTX%';
-- 配列要素の検索
SELECT name, tags, price
FROM products
WHERE 'gaming' = ANY(tags);
-- ネストしたJSONB値の検索
SELECT name, specifications->'display'->>'resolution' as resolution
FROM products
WHERE (specifications->'display'->>'refresh_rate')::INTEGER >= 120;
-- 全文検索(pg_trgm使用)
SELECT name, description,
similarity(name, 'laptop') as name_similarity
FROM products
WHERE name % 'laptop'
ORDER BY name_similarity DESC;
-- ウィンドウ関数とCTE
WITH monthly_sales AS (
SELECT
DATE_TRUNC('month', created_at) as month,
COUNT(*) as product_count,
AVG(price) as avg_price
FROM products
GROUP BY DATE_TRUNC('month', created_at)
)
SELECT
month,
product_count,
avg_price,
LAG(product_count) OVER (ORDER BY month) as prev_month_count,
product_count - LAG(product_count) OVER (ORDER BY month) as growth
FROM monthly_sales
ORDER BY month;
Aurora Serverless設定とオートスケーリング
# Aurora Serverless v2 クラスター作成
aws rds create-db-cluster \
--db-cluster-identifier myapp-serverless-cluster \
--engine aurora-mysql \
--engine-mode provisioned \
--scaling-configuration \
MinCapacity=0.5,MaxCapacity=16,AutoPause=true,SecondsUntilAutoPause=300 \
--master-username admin \
--master-user-password MySecurePassword123 \
--vpc-security-group-ids sg-12345678 \
--db-subnet-group-name myapp-subnet-group
# Aurora Serverless v2 インスタンス作成
aws rds create-db-instance \
--db-instance-identifier myapp-serverless-instance \
--db-cluster-identifier myapp-serverless-cluster \
--db-instance-class db.serverless \
--engine aurora-mysql
# Aurora DSQL(分散SQL)クラスター作成
aws aurora-dsql create-cluster \
--identifier myapp-dsql-cluster \
--engine aurora-dsql \
--engine-version 1.0 \
--vpc-configuration \
VpcId=vpc-12345678,SubnetIds=subnet-12345678,subnet-87654321 \
--tags Key=Environment,Value=production Key=Application,Value=myapp
# クラスターのスケーリング設定変更
aws rds modify-current-db-cluster-capacity \
--db-cluster-identifier myapp-serverless-cluster \
--capacity 4 \
--seconds-before-timeout 300
# オートスケーリング設定
aws application-autoscaling register-scalable-target \
--service-namespace rds \
--scalable-dimension rds:cluster:ReadReplicaCount \
--resource-id cluster:myapp-aurora-cluster \
--min-capacity 1 \
--max-capacity 15
aws application-autoscaling put-scaling-policy \
--service-namespace rds \
--scalable-dimension rds:cluster:ReadReplicaCount \
--resource-id cluster:myapp-aurora-cluster \
--policy-name cpu-scaling-policy \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration \
'{
"TargetValue": 70.0,
"PredefinedMetricSpecification": {
"PredefinedMetricType": "RDSReaderAverageCPUUtilization"
},
"DisableScaleIn": false
}'
バックアップ・復旧とマルチリージョン設定
# 手動スナップショット作成
aws rds create-db-cluster-snapshot \
--db-cluster-identifier myapp-aurora-cluster \
--db-cluster-snapshot-identifier myapp-aurora-snapshot-$(date +%Y%m%d-%H%M%S) \
--tags Key=CreatedBy,Value=backup-script Key=Retention,Value=30days
# ポイントインタイムリカバリ
aws rds restore-db-cluster-to-point-in-time \
--source-db-cluster-identifier myapp-aurora-cluster \
--db-cluster-identifier myapp-aurora-recovered \
--restore-to-time 2024-01-15T10:30:00.000Z \
--vpc-security-group-ids sg-12345678 \
--db-subnet-group-name myapp-subnet-group
# Global Database作成(マルチリージョン)
aws rds create-global-cluster \
--global-cluster-identifier myapp-global-cluster \
--source-db-cluster-identifier myapp-aurora-cluster \
--engine aurora-mysql \
--engine-version 8.0.mysql_aurora.3.02.0
# セカンダリリージョンにクラスター追加
aws rds create-db-cluster \
--region us-west-2 \
--db-cluster-identifier myapp-aurora-cluster-west \
--engine aurora-mysql \
--global-cluster-identifier myapp-global-cluster \
--vpc-security-group-ids sg-87654321 \
--db-subnet-group-name myapp-subnet-group-west
# 暗号化設定
aws rds create-db-cluster \
--db-cluster-identifier myapp-encrypted-cluster \
--engine aurora-postgresql \
--master-username postgres \
--master-user-password MySecurePassword123 \
--storage-encrypted \
--kms-key-id arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012 \
--vpc-security-group-ids sg-12345678
# クロスリージョンバックアップコピー
aws rds copy-db-cluster-snapshot \
--source-db-cluster-snapshot-identifier arn:aws:rds:us-east-1:123456789012:cluster-snapshot:myapp-aurora-snapshot-20240115 \
--target-db-cluster-snapshot-identifier myapp-aurora-snapshot-west-20240115 \
--region us-west-2 \
--kms-key-id arn:aws:kms:us-west-2:123456789012:key/87654321-4321-4321-4321-210987654321
監視・パフォーマンス分析
# CloudWatch メトリクス確認
aws cloudwatch get-metric-statistics \
--namespace AWS/RDS \
--metric-name DatabaseConnections \
--dimensions Name=DBClusterIdentifier,Value=myapp-aurora-cluster \
--start-time 2024-01-15T00:00:00Z \
--end-time 2024-01-15T23:59:59Z \
--period 3600 \
--statistics Average,Maximum
# パフォーマンスインサイト有効化
aws rds modify-db-instance \
--db-instance-identifier myapp-aurora-instance-1 \
--enable-performance-insights \
--performance-insights-retention-period 7
# 拡張監視有効化
aws rds modify-db-instance \
--db-instance-identifier myapp-aurora-instance-1 \
--monitoring-interval 60 \
--monitoring-role-arn arn:aws:iam::123456789012:role/rds-monitoring-role
# ログファイル確認
aws rds describe-db-log-files \
--db-instance-identifier myapp-aurora-instance-1
aws rds download-db-log-file-portion \
--db-instance-identifier myapp-aurora-instance-1 \
--log-file-name error/mysql-error.log \
--starting-token 0
# CloudWatch アラーム設定
aws cloudwatch put-metric-alarm \
--alarm-name "Aurora-High-CPU" \
--alarm-description "Aurora cluster CPU utilization" \
--metric-name CPUUtilization \
--namespace AWS/RDS \
--statistic Average \
--period 300 \
--threshold 80 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 2 \
--alarm-actions arn:aws:sns:us-east-1:123456789012:aurora-alerts \
--dimensions Name=DBClusterIdentifier,Value=myapp-aurora-cluster
アプリケーション統合例
# Python(pymysql + Aurora MySQL)
import pymysql
import boto3
import os
from contextlib import contextmanager
class AuroraConnection:
def __init__(self):
self.writer_endpoint = os.environ['AURORA_WRITER_ENDPOINT']
self.reader_endpoint = os.environ['AURORA_READER_ENDPOINT']
self.username = os.environ['DB_USERNAME']
self.password = os.environ['DB_PASSWORD']
self.database = os.environ['DB_NAME']
@contextmanager
def get_writer_connection(self):
"""書き込み用コネクション(ライターエンドポイント)"""
connection = None
try:
connection = pymysql.connect(
host=self.writer_endpoint,
user=self.username,
password=self.password,
database=self.database,
charset='utf8mb4',
autocommit=False,
connect_timeout=10,
read_timeout=30,
write_timeout=30
)
yield connection
finally:
if connection:
connection.close()
@contextmanager
def get_reader_connection(self):
"""読み取り用コネクション(リーダーエンドポイント)"""
connection = None
try:
connection = pymysql.connect(
host=self.reader_endpoint,
user=self.username,
password=self.password,
database=self.database,
charset='utf8mb4',
autocommit=True, # 読み取りのみなのでautocommit
connect_timeout=10,
read_timeout=30
)
yield connection
finally:
if connection:
connection.close()
# 使用例
aurora = AuroraConnection()
# 書き込み操作
def create_user(username, email, first_name, last_name):
with aurora.get_writer_connection() as conn:
try:
with conn.cursor() as cursor:
sql = """
INSERT INTO users (username, email, first_name, last_name)
VALUES (%s, %s, %s, %s)
"""
cursor.execute(sql, (username, email, first_name, last_name))
user_id = cursor.lastrowid
conn.commit()
return user_id
except Exception as e:
conn.rollback()
raise
# 読み取り操作
def get_users_by_date_range(start_date, end_date):
with aurora.get_reader_connection() as conn:
with conn.cursor(pymysql.cursors.DictCursor) as cursor:
sql = """
SELECT id, username, email, first_name, last_name, created_at
FROM users
WHERE created_at BETWEEN %s AND %s
ORDER BY created_at DESC
LIMIT 1000
"""
cursor.execute(sql, (start_date, end_date))
return cursor.fetchall()
# PostgreSQLとpsycopg2を使用した例
import psycopg2
from psycopg2.extras import RealDictCursor
import json
class AuroraPostgreSQLConnection:
def __init__(self):
self.writer_endpoint = os.environ['AURORA_PG_WRITER_ENDPOINT']
self.reader_endpoint = os.environ['AURORA_PG_READER_ENDPOINT']
self.username = os.environ['DB_USERNAME']
self.password = os.environ['DB_PASSWORD']
self.database = os.environ['DB_NAME']
@contextmanager
def get_connection(self, read_only=False):
endpoint = self.reader_endpoint if read_only else self.writer_endpoint
connection = None
try:
connection = psycopg2.connect(
host=endpoint,
user=self.username,
password=self.password,
database=self.database,
connect_timeout=10,
cursor_factory=RealDictCursor
)
if read_only:
connection.set_session(readonly=True)
yield connection
finally:
if connection:
connection.close()
# JSONBクエリの例
def search_products_by_specs(gpu_brand=None, min_memory_gb=None):
aurora_pg = AuroraPostgreSQLConnection()
with aurora_pg.get_connection(read_only=True) as conn:
with conn.cursor() as cursor:
conditions = []
params = []
if gpu_brand:
conditions.append("specifications->>'gpu' ILIKE %s")
params.append(f'%{gpu_brand}%')
if min_memory_gb:
conditions.append("(specifications->>'memory')::INTEGER >= %s")
params.append(min_memory_gb)
where_clause = " AND ".join(conditions) if conditions else "1=1"
sql = f"""
SELECT
name,
specifications,
tags,
price,
specifications->>'gpu' as gpu,
specifications->>'memory' as memory
FROM products
WHERE {where_clause}
ORDER BY price DESC
"""
cursor.execute(sql, params)
return cursor.fetchall()
# 使用例
products = search_products_by_specs(gpu_brand='RTX', min_memory_gb=16)
for product in products:
print(f"Name: {product['name']}")
print(f"GPU: {product['gpu']}")
print(f"Memory: {product['memory']}")
print(f"Price: ${product['price']}")
print("---")
Terraform でのAurora構築
# terraform/aurora.tf
resource "aws_rds_cluster" "aurora_mysql" {
cluster_identifier = "myapp-aurora-cluster"
engine = "aurora-mysql"
engine_version = "8.0.mysql_aurora.3.02.0"
database_name = "myapp_production"
master_username = "admin"
master_password = var.db_password
vpc_security_group_ids = [aws_security_group.aurora.id]
db_subnet_group_name = aws_db_subnet_group.aurora.name
backup_retention_period = 7
preferred_backup_window = "03:00-04:00"
preferred_maintenance_window = "sun:04:00-sun:05:00"
enabled_cloudwatch_logs_exports = ["error", "general", "slow-query"]
storage_encrypted = true
kms_key_id = aws_kms_key.aurora.arn
deletion_protection = true
skip_final_snapshot = false
final_snapshot_identifier = "myapp-aurora-final-snapshot"
tags = {
Environment = "production"
Application = "myapp"
}
}
resource "aws_rds_cluster_instance" "aurora_instances" {
count = 2
identifier = "myapp-aurora-instance-${count.index + 1}"
cluster_identifier = aws_rds_cluster.aurora_mysql.id
instance_class = "db.r6g.xlarge"
engine = aws_rds_cluster.aurora_mysql.engine
engine_version = aws_rds_cluster.aurora_mysql.engine_version
auto_minor_version_upgrade = true
monitoring_interval = 60
monitoring_role_arn = aws_iam_role.rds_monitoring.arn
performance_insights_enabled = true
performance_insights_retention_period = 7
tags = {
Environment = "production"
Application = "myapp"
}
}
# Global Database
resource "aws_rds_global_cluster" "global" {
global_cluster_identifier = "myapp-global-cluster"
source_db_cluster_identifier = aws_rds_cluster.aurora_mysql.arn
engine = "aurora-mysql"
engine_version = "8.0.mysql_aurora.3.02.0"
deletion_protection = true
}
# セカンダリリージョンクラスター
resource "aws_rds_cluster" "aurora_secondary" {
provider = aws.us_west_2
cluster_identifier = "myapp-aurora-cluster-west"
engine = "aurora-mysql"
global_cluster_identifier = aws_rds_global_cluster.global.id
vpc_security_group_ids = [aws_security_group.aurora_west.id]
db_subnet_group_name = aws_db_subnet_group.aurora_west.name
tags = {
Environment = "production"
Application = "myapp"
Region = "us-west-2"
}
depends_on = [aws_rds_global_cluster.global]
}
# セキュリティグループ
resource "aws_security_group" "aurora" {
name_prefix = "aurora-sg"
vpc_id = var.vpc_id
ingress {
from_port = 3306
to_port = 3306
protocol = "tcp"
cidr_blocks = [var.vpc_cidr]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "aurora-security-group"
}
}
# 出力
output "aurora_writer_endpoint" {
value = aws_rds_cluster.aurora_mysql.endpoint
}
output "aurora_reader_endpoint" {
value = aws_rds_cluster.aurora_mysql.reader_endpoint
}
output "aurora_cluster_identifier" {
value = aws_rds_cluster.aurora_mysql.cluster_identifier
}