> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# الدليل السريع لـ Managed Postgres

> اختبر أداء Postgres المعزّز بـ NVMe وأضف التحليل في الوقت الفعلي عبر تكامل ClickHouse الأصلي

تتناول هذه الصفحة تهيئة ClickHouse Managed Postgres، وتحميل البيانات، ونسخها إلى ClickHouse، والاستعلام عنها، وكل ذلك من خلال سطر الأوامر باستخدام [ClickHouse CLI](/docs/ar/products/cloud/features/cli) (`clickhousectl`) و`psql`. الأوامر غير تفاعلية؛ ويُخرج `clickhousectl` مخرجات JSON مع `--json`.

<div id="prerequisites">
  ## المتطلبات الأساسية
</div>

ثبّت ClickHouse CLI:

```bash theme={null}
curl https://clickhouse.com/cli | sh
```

ستحتاج أيضًا إلى `psql` (أدوات عميل PostgreSQL؛ على MacOS، `brew install libpq`) و`jq`.

تتطلب عمليات الكتابة (الإنشاء، الحذف) [المصادقة بمفتاح API](/docs/ar/products/cloud/features/admin-features/api/openapi)؛ أما تسجيل الدخول عبر OAuth فهو للقراءة فقط:

```bash theme={null}
clickhousectl cloud auth login --api-key <YOUR_KEY> --api-secret <YOUR_SECRET>
```

بدلًا من ذلك، عيّن متغيرَي البيئة `CLICKHOUSE_CLOUD_API_KEY` و`CLICKHOUSE_CLOUD_API_SECRET`. تحقّق باستخدام `clickhousectl cloud auth status`؛ ومن المفترض أن يظهر إدخال بنطاق `read/write`.

<div id="part-1-create-and-load">
  ## الجزء 1: إنشاء Postgres وتحميل البيانات
</div>

<div id="create-postgres-service">
  ### أنشئ خدمة Postgres
</div>

أنشئ الخدمة واحفظ الاستجابة، إذ لا تُعرض كلمة المرور إلا مرة واحدة:

```bash theme={null}
clickhousectl cloud postgres create \
  --name quickstart-pg \
  --region us-east-1 \
  --size c6gd.large \
  --pg-version 18 \
  --json > pg.json
```

تتضمن الاستجابة معرّف الخدمة، واسم المضيف، وسلسلة اتصال جاهزة للاستخدام:

```json theme={null}
{
  "id": "3b5a3112-bf02-82d0-bd02-fbe67d5caa7a",
  "name": "quickstart-pg",
  "provider": "aws",
  "region": "us-east-1",
  "postgresVersion": "18",
  "size": "c6gd.large",
  "storageSize": 118,
  "haType": "none",
  "state": "creating",
  "createdAt": "2026-07-22T13:21:22Z",
  "hostname": "quickstart-pg-c1406b50.pg7dd324nz0a1qm1fqskxbjn7m.c0.us-east-1.aws.pg.clickhouse.cloud",
  "username": "postgres",
  "password": "vV6cfEr2p_-TzkCDrZOx",
  "connectionString": "postgres://postgres:vV6cfEr2p_-TzkCDrZOx@quickstart-pg-c1406b50.pg7dd324nz0a1qm1fqskxbjn7m.c0.us-east-1.aws.pg.clickhouse.cloud:5432/postgres?channel_binding=require",
  "isPrimary": true,
  "tags": []
}
```

استخرج ما تحتاج إليه بقية هذا الدليل:

```bash theme={null}
PG_ID=$(jq -r .id pg.json)
PG_URL=$(jq -r .connectionString pg.json)
```

إذا فُقدت كلمة المرور، فأنشئ كلمة مرور جديدة باستخدام الأمر `clickhousectl cloud postgres reset-password $PG_ID --generate`.

<div id="wait-for-provisioning">
  ### انتظر حتى يكتمل تجهيز الخدمة
</div>

تستغرق عملية التجهيز بضع دقائق. تحقّق دوريًا حتى تصبح الحالة `running`:

```bash theme={null}
while [ "$(clickhousectl cloud postgres get "$PG_ID" --json | jq -r .state)" != "running" ]; do
  sleep 15
done
```

<div id="load-sample-data">
  ### تحميل بيانات نموذجية
</div>

أنشئ جدولين ونفّذ insert لمليون حدث عبر `psql`:

```bash theme={null}
psql "$PG_URL" <<'SQL'
\timing
CREATE TABLE events (
   event_id SERIAL PRIMARY KEY,
   event_name VARCHAR(255) NOT NULL,
   event_type VARCHAR(100),
   event_timestamp TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
   event_data JSONB,
   user_id INT,
   user_ip INET,
   is_active BOOLEAN DEFAULT TRUE,
   created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
   updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE users (
   user_id SERIAL PRIMARY KEY,
   name VARCHAR(100),
   country VARCHAR(50),
   platform VARCHAR(50)
);

INSERT INTO events (event_name, event_type, event_timestamp, event_data, user_id, user_ip)
SELECT
   'Event ' || gs::text AS event_name,
   CASE
       WHEN random() < 0.5 THEN 'click'
       WHEN random() < 0.75 THEN 'view'
       WHEN random() < 0.9 THEN 'purchase'
       WHEN random() < 0.98 THEN 'signup'
       ELSE 'logout'
   END AS event_type,
   NOW() - INTERVAL '1 day' * (gs % 365) AS event_timestamp,
   jsonb_build_object('key', 'value' || gs::text, 'additional_info', 'info_' || (gs % 100)::text) AS event_data,
   GREATEST(1, LEAST(1000, FLOOR(POWER(random(), 2) * 1000) + 1)) AS user_id,
   ('192.168.1.' || ((gs % 254) + 1))::inet AS user_ip
FROM
   generate_series(1, 1000000) gs;

INSERT INTO users (name, country, platform)
SELECT
    first_names[first_idx] || ' ' || last_names[last_idx] AS name,
    CASE
        WHEN random() < 0.25 THEN 'India'
        WHEN random() < 0.5 THEN 'USA'
        WHEN random() < 0.7 THEN 'Germany'
        WHEN random() < 0.85 THEN 'China'
        ELSE 'Other'
    END AS country,
    CASE
        WHEN random() < 0.2 THEN 'iOS'
        WHEN random() < 0.4 THEN 'Android'
        WHEN random() < 0.6 THEN 'Web'
        WHEN random() < 0.75 THEN 'Windows'
        WHEN random() < 0.9 THEN 'MacOS'
        ELSE 'Linux'
    END AS platform
FROM
    generate_series(1, 1000) AS seq
    CROSS JOIN LATERAL (
        SELECT
            array['Alice', 'Bob', 'Charlie', 'Diana', 'Eve', 'Frank', 'Grace', 'Hank', 'Ivy', 'Jack', 'Liam', 'Olivia', 'Noah', 'Emma', 'Sophia', 'Benjamin', 'Isabella', 'Lucas', 'Mia', 'Amelia', 'Aarav', 'Riya', 'Arjun', 'Ananya', 'Wei', 'Li', 'Huan', 'Mei', 'Hans', 'Klaus', 'Greta', 'Sofia'] AS first_names,
            array['Smith', 'Johnson', 'Williams', 'Brown', 'Jones', 'Garcia', 'Miller', 'Davis', 'Martinez', 'Taylor', 'Anderson', 'Thomas', 'Jackson', 'White', 'Harris', 'Martin', 'Thompson', 'Moore', 'Lee', 'Perez', 'Sharma', 'Patel', 'Gupta', 'Reddy', 'Zhang', 'Wang', 'Chen', 'Liu', 'Schmidt', 'Müller', 'Weber', 'Fischer'] AS last_names,
            1 + (seq % 32) AS first_idx,
            1 + ((seq / 32)::int % 32) AS last_idx
    ) AS names;
SQL
```

```text theme={null}
Timing is on.
CREATE TABLE
Time: 86.029 ms
CREATE TABLE
Time: 80.962 ms
INSERT 0 1000000
Time: 7120.357 ms (00:07.120)
INSERT 0 1000
Time: 84.807 ms
```

يكتمل إدراج مليون صف خلال نحو 7 ثوانٍ على `c6gd.large` (أصغر فئة) بفضل تخزين NVMe. تحقّق من ذلك بإجراء استعلام؛ إذ تختلف أعداد الصفوف بين مرات التشغيل لأن البيانات تُولَّد باستخدام `random()`:

```bash theme={null}
psql "$PG_URL" -c "SELECT event_type, COUNT(*) FROM events GROUP BY event_type ORDER BY 2 DESC;"
```

<div id="part-2-replicate">
  ## الجزء 2: النسخ إلى ClickHouse
</div>

<div id="create-clickhouse-service">
  ### أنشئ خدمة ClickHouse
</div>

أنشئ خدمة في المنطقة نفسها واحفظ الاستجابة؛ إذ لا تظهر كلمة المرور إلا في استجابة الإنشاء:

```bash theme={null}
clickhousectl cloud service create \
  --name quickstart-ch \
  --region us-east-1 \
  --json > ch.json

CH_ID=$(jq -r .service.id ch.json)
CH_PASSWORD=$(jq -r .password ch.json)
```

انتظر حتى يصبح قيد التشغيل؛ إذ يتطلب ClickPipe وجهةً قيد التشغيل:

```bash theme={null}
while [ "$(clickhousectl cloud service get "$CH_ID" --json | jq -r .state)" != "running" ]; do
  sleep 15
done
```

لاستخدام خدمة موجودة بدلًا من ذلك، عيّن `CH_ID` من `clickhousectl cloud service list` وعيّن `CH_PASSWORD` إلى كلمة مرور المستخدم `default` الخاصة بها، والتي تحتاجها خطوة `pg_clickhouse`.

<div id="replicate-to-clickhouse">
  ### انسخ الجداول إلى ClickHouse
</div>

أنشئ ClickPipe لـ Postgres CDC على خدمة ClickHouse، مع توجيهه إلى اسم مضيف الخاص بـ Managed Postgres. ينسخ هذا الـ pipe الصفوف الحالية، ثم يُبقي ClickHouse متزامنًا مع التغييرات اللاحقة:

```bash theme={null}
PG_HOST=$(jq -r .hostname pg.json)
PG_PASSWORD=$(jq -r .password pg.json)

clickhousectl cloud clickpipe create postgres "$CH_ID" \
  --name quickstart-sync \
  --host "$PG_HOST" \
  --pg-database postgres \
  --username postgres \
  --password "$PG_PASSWORD" \
  --table-mapping public.events:public_events \
  --table-mapping public.users:public_users \
  --json > pipe.json

PIPE_ID=$(jq -r .id pipe.json)
```

ملاحظات:

* تُنشأ الجداول المُكرَّرة في قاعدة البيانات `default` على خدمة ClickHouse، وتُسمّى بحسب أهداف `--table-mapping`
* يُنشأ كلٌّ من الـ publication وreplication slot تلقائيًا، ويقتصر نطاق الـ publication على الجداول المعيّنة؛ مرّر `--publication-name` لاستخدام اسم تديره بنفسك
* استخدم اسم مضيف المباشر لـ Postgres؛ replication غير مدعومة عبر PgBouncer

<div id="wait-for-pipe">
  ### انتظر حتى تصل القناة إلى `Running`
</div>

تنتقل القناة عبر `Provisioning` و`Setup` و(بالنسبة إلى الجداول الأكبر) `Snapshot` قبل أن تصل إلى `Running`، ويستغرق ذلك نحو 4 دقائق لأول قناة في خدمة. وتُعد حالتا `Failed` و`InternalError` نهائيتين:

```bash theme={null}
while :; do
  STATE=$(clickhousectl cloud clickpipe get "$CH_ID" "$PIPE_ID" --json | jq -r .state)
  case "$STATE" in
    Running) break ;;
    Failed|InternalError) echo "ClickPipe entered terminal state: $STATE" >&2; exit 1 ;;
  esac
  sleep 15
done
```

<div id="query-clickhouse">
  ### استعلِم عن البيانات المُكرَّرة في ClickHouse
</div>

نفّذ استعلامات SQL على خدمة ClickHouse مباشرةً من خلال CLI. تنشئ أول عملية استدعاء تلقائيًا نقطة نهاية لواجهة برمجة تطبيقات الاستعلام ومفتاح API مقيّدًا بنطاق الخدمة:

```bash theme={null}
clickhousectl cloud service query --id "$CH_ID" \
  --query "SELECT count() FROM public_events"
```

```text theme={null}
Provisioning Query API endpoint + key for service 'quickstart-ch'...
1000000
```

تُنسَخ عمليات الكتابة الجديدة في Postgres باستمرار. أدرِج صفًا وأجرِ poll حتى يصل العدد إلى 1,000,001 (عادةً خلال أقل من دقيقة):

```bash theme={null}
psql "$PG_URL" -c "INSERT INTO events (event_name, event_type, user_id, user_ip) VALUES ('cdc-test', 'click', 42, '10.0.0.1');"

while [ "$(clickhousectl cloud service query --id "$CH_ID" \
  --query "SELECT count() FROM public_events")" != "1000001" ]; do
  sleep 10
done
```

<div id="query-clickhouse-from-postgres">
  ### الاستعلام عن ClickHouse من Postgres
</div>

يتيح الامتداد [`pg_clickhouse`](/docs/ar/products/managed-postgres/extensions/pg_clickhouse/introduction) لـ Postgres العمل كطبقة استعلام موحّدة لكلٍّ من البيانات المعاملاتية والتحليلية. احصل على اسم مضيف ClickHouse عبر HTTPS، ثم أعدّ الامتداد باستخدام `psql`:

```bash theme={null}
CH_HOST=$(clickhousectl cloud service get "$CH_ID" --json \
  | jq -r '.endpoints[] | select(.protocol=="https") | .host')

psql "$PG_URL" <<SQL
CREATE EXTENSION pg_clickhouse;
CREATE SERVER ch FOREIGN DATA WRAPPER clickhouse_fdw
       OPTIONS(driver 'http', host '$CH_HOST', dbname 'default', port '8443');
CREATE USER MAPPING FOR CURRENT_USER SERVER ch
       OPTIONS (user 'default', password '$CH_PASSWORD');
CREATE SCHEMA organization;
IMPORT FOREIGN SCHEMA "default" FROM SERVER ch INTO organization;
SQL
```

تم ترك Heredoc بدون علامات اقتباس عمدًا، لكي يستبدل مفسّر الأوامر `$CH_HOST` و`$CH_PASSWORD` قبل أن يصل SQL إلى Postgres. أصبحت الجداول المُكرَّرة الآن مرئية كجداول خارجية في مخطط `organization`؛ وتُنفَّذ الاستعلامات عليها في ClickHouse.

عند القياس على `c6gd.large` باستخدام مجموعة البيانات هذه، تعمل الاستعلامات التحليلية أسرع بمقدار 6–9 مرات عبر الجداول الخارجية (على سبيل المثال، GROUP BY مع 5 عمليات تجميع: ‏176 مللي ثانية عبر ClickHouse مقابل 1,133 مللي ثانية محليًا؛ وJOIN مع عمليات تجميع: ‏298 مللي ثانية مقابل 2,764 مللي ثانية).

<div id="cleanup-resources">
  ## التنظيف
</div>

احذف ClickPipe أولًا، ثم خدمة Postgres. يؤدي حذف الخدمة إلى إزالة جميع بياناتها نهائيًا:

```bash theme={null}
clickhousectl cloud clickpipe delete "$CH_ID" "$PIPE_ID"
clickhousectl cloud postgres delete "$PG_ID"
```

لا يمكن حذف خدمة ClickHouse وهي قيد التشغيل مباشرةً. أوقفها، وانتظر حتى تصبح `stopped`، ثم احذفها:

```bash theme={null}
clickhousectl cloud service stop "$CH_ID"

while [ "$(clickhousectl cloud service get "$CH_ID" --json | jq -r .state)" != "stopped" ]; do
  sleep 10
done

clickhousectl cloud service delete "$CH_ID"
```
