-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsection_5.txt
More file actions
399 lines (242 loc) · 16.5 KB
/
Copy pathsection_5.txt
File metadata and controls
399 lines (242 loc) · 16.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
Təsəvvür elə ki, sənin bir serverin var və sən orada ASP.NET Core tətbiqini işlədirsən.
Bu tətbiqə mütləq bir verilənlər bazası lazımdır. Seçimin PostgreSQL-dir.
Ənənəvi yol belə idi:
Sən serverə daxil olurdun, `apt install postgresql` yazırdın və Postgres host əməliyyat sisteminə quraşdırılırdı.
İndi hər şey həmin hostun özündə idi.
Postgres-in proqram faylları `/usr/lib/postgresql`, konfiqurasiya faylları `/etc/postgresql`, məlumat faylları isə `/var/lib/postgresql` qovluğuna düşürdü.
Yəni hər şey sənin serverinlə sıx bağlı idi.
Burada dərhal bir neçə problem çıxırdı. Məsələn,
1. sən sabah başqa serverə köçməlisən. O serverdə Ubuntu 22.04 deyil, CentOS var.
CentOS-un repolarında Postgres 12 var, amma sən tətbiqi 16 ilə sınaqdan keçirmisən.
Birdən versiya fərqi ucbatından kod işləməyəcək.
Digər problem:
2. sən Postgres-i upgrade etmək istəyirsən, amma `apt upgrade` desən, sistemdə başqa paketlər də dəyişəcək və yeni dependency-lər problem yaradacaq.
Ən pisi də odur ki, Postgres-i tam silib təmizləmək çətindir – fayllar bir az `etc`-də qalır, bir az `var`-da qalır.
İndi isə təsəvvür elə ki, Docker ilə işləyirsən. `docker run postgres:16` deyirsən və sənə hazır PostgreSQL 16 serveri gəlir.
İçində hər şey var – server binar faylları, lazımi kitabxanalar, default konfiqurasiya.
Əgər sabah sən başqa serverə köçsən, yenə də sadəcə `docker run postgres:16` yazırsan və həmin eyni Postgres qalxır.
Heç hostun paketlərinə, hansı distributiv olduğuna baxmırsan.
Praktik bir nümunə:
sən komandanın içindəsən, hər kəsdə fərqli laptop var – kimdə Mac, kimdə Windows, kimdə Linux.
Əvvəllər hər kəs öz kompüterinə Postgres qururdu. Birində 14 idi, birində 15, birdən kimsə `pg_dump` faylı yaradırdı və digərinin versiyası o faylı oxuya bilmirdi.
İndi isə hər kəs `docker run postgres:16` yazır və hamıda eyni Postgres, eyni versiya qalxır. Problem kökündən həll olunur.
Başqa bir misal: sən test üçün 3 fərqli layihə işləyirsən. Birincisi Postgres 12 tələb edir, ikincisi 14, üçüncüsü isə ən sonuncu 16.
Əgər bunları hosta quraşdırmaq istəsən, çox qarışacaq, çünki eyni maşında eyni anda bir neçə versiyanı saxlamaq müşkül işdir. Amma Docker ilə çox rahatdır:
```bash
docker run --name pg12 -e POSTGRES_PASSWORD=pass -d postgres:12
docker run --name pg14 -e POSTGRES_PASSWORD=pass -d postgres:14
docker run --name pg16 -e POSTGRES_PASSWORD=pass -d postgres:16
```
Üçü də paralel işləyir. Bir-birinə qarışmır, çünki hər biri öz konteynerində, öz fayl sistemi ilə yaşayır.
Bu, konteyner yanaşmasının ən böyük gücüdür: sən PostgreSQL-i artıq host sisteminə deyil, image-ə bağlayırsan.
Yəni Postgres bir “qutuda” gəlir. Qutuda onun versiyası, lazımi kitabxanaları, default konfiqurasiyası hazır olur.
Sən bu qutunu harada açsan, nəticə eynidir.
Bunun üstünlüyü həm də təmizliyindədir. Əgər hostda Postgres-i silmək istəsən, bir az fayl burada qalır, bir az orada.
Konteynerdə isə sadəcə `docker rm -v mypostgres` yazırsan və hər şey tamamilə təmizlənir.
Beləcə, konteyner yanaşması sənə üç böyük fayda gətirir:
1. Hara köçsən, eyni nəticə alırsan.
2. Versiyaları dəyişmək və idarə etmək asan olur.
3. Quraşdırmaq və təmizləmək çox rahatdır.
----------------------------------------------------------------------------------------------------
1. Volume məsələsi niyə bu qədər vacibdir?
Postgres bir verilənlər bazasıdır, yəni bütün işini fayllar üzərində görür.
Sən bir CREATE TABLE, INSERT INTO etsən, əslində bunlar diskdə fayllara yazılır. Amma konteynerin özünün yazı qatı müvəqqətidir.
Sadə nümunə: docker run --name pgtest -e POSTGRES_PASSWORD=1234 -d postgres:16
commandını icra etsək, postgres16 image istifadə edib detach modda yeni kontainer yaradacıyıq.
İndi docker exec -it pgtest psql -U postgres ilə bazaya gir və bir cədvəl yaradaq:
postgres=# CREATE DATABASE mydb;
CREATE DATABASE
postgres=# \c mydb
You are now connected to database "mydb" as user "postgres".
mydb-# \l
List of databases
Name | Owner | Encoding | Locale Provider | Collate | Ctype | ICU Locale | ICU Rules | Access privileges
-----------+----------+----------+-----------------+------------+------------+------------+-----------+-----------------------
mydb | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | |
postgres | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | |
template0 | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | | =c/postgres +
| | | | | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | | =c/postgres +
| | | | | | | | postgres=CTc/postgres
(4 rows)
mydb-# \dt
List of relations
Schema | Name | Type | Owner
--------+-------+-------+----------
public | users | table | postgres
(1 row)
mydb=# CREATE TABLE users(id SERIAL PRIMARY KEY, name TEXT);
CREATE TABLE
mydb=# INSERT INTO users(name) VALUES('Mahammad');
INSERT 0 1
mydb=# \dt
List of relations
Schema | Name | Type | Owner
--------+-------+-------+----------
public | users | table | postgres
(1 row)
mydb=# select * from users;
id | name
----+----------
1 | Mahammad
(1 row)
Hamısı işləyir. Amma indi:
docker rm -f pgtest
docker run --name pgtest -e POSTGRES_PASSWORD=1234 -d postgres:16
docker exec -it pgtest psql -U postgres
Yenidən girəndə görəcəksən ki, mydb yoxdur, users cədvəli də getdi. Çünki konteyner silinəndə onun yazı qatı da silinir.
postgres-# \l
List of databases
Name | Owner | Encoding | Locale Provider | Collate | Ctype | ICU Locale | ICU Rules | Access privileges
-----------+----------+----------+-----------------+------------+------------+------------+-----------+-----------------------
postgres | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | |
template0 | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | | =c/postgres +
| | | | | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | | =c/postgres +
| | | | | | | | postgres=CTc/postgres
(3 rows)
----------------------------------------------------------------------------------------------------
Volume ilə necə dəyişir?
İndi belə edək:
PS C:\Users\mahammada> docker run --name pgvolume --detach -e POSTGRES_PASSWORD=1234 -v pg_data:/var/lib/postgresql/data postgres:16
b0b50bef5b4827df566eda7f2181501d0d100206d41c9724edb121e5431523ec
PS C:\Users\mahammada> docker exec -it pgvolume psql -U postgres
psql (16.10 (Debian 16.10-1.pgdg13+1))
Type "help" for help.
postgres-# \l
List of databases
Name | Owner | Encoding | Locale Provider | Collate | Ctype | ICU Locale | ICU Rules | Access privileges
-----------+----------+----------+-----------------+------------+------------+------------+-----------+-----------------------
postgres | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | |
template0 | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | | =c/postgres +
| | | | | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | | =c/postgres +
| | | | | | | | postgres=CTc/postgres
(3 rows)
postgres=# CREATE DATABASE mydb;
CREATE DATABASE
postgres=# \c mydb;
You are now connected to database "mydb" as user "postgres".
mydb=# \l
List of databases
Name | Owner | Encoding | Locale Provider | Collate | Ctype | ICU Locale | ICU Rules | Access privileges
-----------+----------+----------+-----------------+------------+------------+------------+-----------+-----------------------
mydb | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | |
postgres | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | |
template0 | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | | =c/postgres +
| | | | | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | | =c/postgres +
| | | | | | | | postgres=CTc/postgres
(4 rows)
mydb=# CREATE TABLE users(id SERIAL PRIMARY KEY, name TEXT);
CREATE TABLE
mydb=# \dt
List of relations
Schema | Name | Type | Owner
--------+-------+-------+----------
public | users | table | postgres
(1 row)
mydb=# insert into users(name) values('mahammad');
INSERT 0 1
mydb=# select * from users;
id | name
----+----------
1 | mahammad
(1 row)
mydb=# exit
Bu dəfə Postgres-in data qovluğu pg_data adlı named volume-a yazılır.
Indi konteyneri silib yeniden daxil oluruq hemin image ile containere.
PS C:\Users\mahammada> docker ps --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b0b50bef5b48 postgres:16 "docker-entrypoint.s…" 10 minutes ago Up 10 minutes 5432/tcp pgvolume
d389957cb1ba learn-kazakh-client:latest "/docker-entrypoint.…" 3 hours ago Up 3 hours 0.0.0.0:8081->80/tcp client
3a0b8f1489d7 learn-kazakh-api:latest "dotnet LearnKazakh.…" 4 hours ago Up 4 hours 0.0.0.0:8080->8080/tcp api
PS C:\Users\mahammada> docker stop pgvolume
pgvolume
PS C:\Users\mahammada> docker rm b0b
b0b
PS C:\Users\mahammada> docker run --name pgvolume --detach -e POSTGRES_PASSWORD=1234 -v pg_data:/var/lib/postgresql/data postgres:16
0c42ae4b9e2f1818367c00afe18153bcd204e9ab9c1ffbac7cd92f2963409aac
PS C:\Users\mahammada> docker exec -it pgvolume psql -U postgres
psql (16.10 (Debian 16.10-1.pgdg13+1))
Type "help" for help.
postgres=# \l
List of databases
Name | Owner | Encoding | Locale Provider | Collate | Ctype | ICU Locale | ICU Rules | Access privileges
-----------+----------+----------+-----------------+------------+------------+------------+-----------+-----------------------
mydb | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | |
postgres | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | |
template0 | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | | =c/postgres +
| | | | | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | | =c/postgres +
| | | | | | | | postgres=CTc/postgres
(4 rows)
Bu dəfə mydb və users cədvəli olduğu kimi qaldı. Çünki məlumat konteynerlə birlikdə ölmədi, volume-da saxlanıldı.
----------------------------------------------------------------------------------------------------
Mühit dəyişənləri (Environment variables)
Rəsmi Postgres image-i ilk dəfə qalxanda bəzi environment dəyişənlərini oxuyur və ona görə ilkin qurulum edir.
Ən əsas üçü:
1. POSTGRES_USER – hansı istifadəçi yaradılsın.
2. POSTGRES_PASSWORD – o istifadəçinin parolu.
3. POSTGRES_DB – başlanğıcda yaradılacaq verilənlər bazası.
Default davranış (verməsən nə olur?)
Əgər bunları heç birini verməsən: docker run --detach --name pgdefault postgres:16
Image default olaraq postgres adlı superuser yaradır. Amma parolsuz.
Bu, sənin lokal test mühitində rahat ola bilər, amma prod mühitdə çox təhlükəlidir – hər kəs bu istifadəçiyə qoşula bilər.
Öz istifadəçini və bazanı yaratmaq
Məsələn:
docker run --detach --name pgapp -e POSTGRES_USER=appuser -e POSTGRES_PASSWORD=secret123 -e POSTGRES_DB=learnkazakh -v pg_data:/var/lib/postgres/data postgres:16
İlk dəfə qalxanda Postgres belə edir:
appuser adlı istifadəçi yaradır.
Ona secret123 parolu təyin edir.
learnkazakh adlı baza yaradır və sahibini appuser edir.
İndi sən birbaşa belə qoşula bilərsən: psql -h localhost -U appuser -d learnkazakh
Yəni artıq default postgres useri ilə işləmək məcburiyyətində deyilsən, öz app-ına aid user və db hazır olur.
----------------------------------------------------------------------------------------------------
Əmrlərin siyahısı, vacib olanlar.
1. Bütün verilənlər bazalarını görmək
psql içində \l yazırsan (kiçik L hərfi).
Bu, serverdə mövcud olan bütün bazaları siyahıya alır: ad, sahib, kodlaşdırma, icazələr.
learnkazakh=# \l
List of databases
Name | Owner | Encoding | Locale Provider | Collate | Ctype | ICU Locale | ICU Rules | Access privileges
-------------+------------+----------+-----------------+------------+------------+------------+-----------+---------------------------
learnkazakh | SUPERADMIN | UTF8 | libc | en_US.utf8 | en_US.utf8 | | |
postgres | SUPERADMIN | UTF8 | libc | en_US.utf8 | en_US.utf8 | | |
template0 | SUPERADMIN | UTF8 | libc | en_US.utf8 | en_US.utf8 | | | =c/SUPERADMIN +
| | | | | | | | SUPERADMIN=CTc/SUPERADMIN
template1 | SUPERADMIN | UTF8 | libc | en_US.utf8 | en_US.utf8 | | | =c/SUPERADMIN +
| | | | | | | | SUPERADMIN=CTc/SUPERADMIN
(4 rows)
2. Bazanı dəyişmək
Məsələn, hazırda postgres bazasındasan, amma mydb-ə keçmək istəyirsən:
\c mydb
Buradakı \c connect deməkdir. İndi sən artıq mydb içindəsən və bütün əmrlər bu bazaya təsir edir.
3. Cədvəlləri görmək
İstədiyin bazaya keçdikdən sonra \dt yazırsan:
Bu, həmin bazadakı bütün cədvəlləri göstərir: ad, sahib, növ, schema. Əgər cədvəl yoxdursa, sadəcə “No relations found” deyir.
learnkazakh=# \dt
List of relations
Schema | Name | Type | Owner
--------+-------+-------+------------
public | users | table | SUPERADMIN
(1 row)
4. Cədvəl yaratmaq və məlumat əlavə etmək
CREATE TABLE users(
id SERIAL PRIMARY KEY,
name TEXT
);
INSERT INTO users(name) VALUES('Mahammad');
INSERT INTO users(name) VALUES('Ulpan');
6. Digər faydalı psql əmrləri
\d users → konkret users cədvəlinin strukturunu göstərir.
learnkazakh=# \d users
Table "public.users"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+-----------------------------------
id | integer | | not null | nextval('users_id_seq'::regclass)
name | text | | |
Indexes:
"users_pkey" PRIMARY KEY, btree (id)
\q → psql-dən çıxmaq.
\? → bütün psql qısa əmrlərinin siyahısı.