14 Kasım 2021 Pazar

Vitess Local Install via Docker - Derleyince Docker Image Oluşur ve Test İçin Kullanılır

Giriş
Buradaki adımları takip edince "vitess/local" isimli bir docker image oluşturuluyor. 
Yani
1. Derleme işleminin Linux üzerinde olması lazım
2. vitess dizinine gideriz ve "make docker_local" komutunu çalıştırırız

vitess/bootstrap:3-common isimli image ile başlıyor. 

Bu image docker'da bulunan "vitess/base" isimli image'dan farklı. Burada VTDATAROOT değişkeninden bahsediliyor. Ne işe yarar bilmiyorum

Dockerfile
vitess\docker\local\Dockerfile dosyasındaki bir satır kullanılan MySQL'in eski olmasını sağlıyor. Bu satır şöyle. MySQL 5.7 kuruluyor
# Install dependencies
COPY docker/lite/install_dependencies.sh /vt/dist/install_dependencies.sh
RUN /vt/dist/install_dependencies.sh mysql57
Bunu şöyle yaparız. Böylece MySQL 8 kuruluyor
# Install dependencies
COPY docker/lite/install_dependencies.sh /vt/dist/install_dependencies.sh
RUN /vt/dist/install_dependencies.sh mysql80
Ancak bunu yapınca JDBC bağlantısı kurarken şu hatayı almaya başlıyoruz. Çünkü vtgate, MySQL 8 veri tabanı ile çalıştığını ilan etmiyor ve MySQL connector sürücüsünün kendine göre akıllı davranıp, vtgate tarafından belirtilen sürüme göre bazı parametreler eklediği söyleniyor. 
"Unknown system variable 'query_cache_size'"
Bu açıklama burada.

vitess\examples\local\scripts\vtgate-up.sh değiştirilirse belki düzelir dedim ama olmadı
-mysql_auth_server_impl none \
-mysql_server_version '8.0.0' \
mysql-connector-java kütüphanesinde sürüm 8.0.27 içinde com/mysql/cj/NativeSession.java dosyasında şöyle bir kod var
if (!versionMeetsMinimum(8, 0, 3)) {
  queryBuf.append(", @@query_cache_size AS query_cache_size");
  queryBuf.append(", @@query_cache_type AS query_cache_type");
}
Bunu gördükten sonra 8.0.0'ın yeterli olmadığını anladım. vitess\examples\local\scripts\vtgate-up.sh dosyasının son hali şöyle oldu
-mysql_auth_server_impl none \
-mysql_server_version '8.0.17' \
Böyle yapınca her şey düzeldi.

Çalıştırma
Derleme işlemi bittikten sonra şu komutu çalıştırırız. 
./docker/local/run.sh
run.sh Değişiklikleri
Ben run.sh dosyasında bazı değişiklikler yaptım. İçi şöyle oldu. --rm, --name ve -p 15306 seçeneklerini ekledim. Çünkü dışarından vtgate'e jdbc bağlantısı açmak istedim
#!/bin/bash
docker run --rm --name vitesslocal -p 15306:15306  -p 15000:15000 -p 15001:15001
  -p 15991:15991 -p 15999:15999 -it vitess/local
Bağlantı için kullanılan jdbc string şöyle
jdbc:mysql://localhost:15306/commerce
Portları görmek için docker içinde şöyle yaparız. 15306 vtgate tarafından dinleniyor.
$ ss -ltp
State     Recv-Q    Send-Q       Local Address:Port        Peer Address:Port
LISTEN    0         4096             127.0.0.1:2379             0.0.0.0:*        users:(("etcd",pid=17,fd=5))
LISTEN    0         4096             127.0.0.1:2380             0.0.0.0:*        users:(("etcd",pid=17,fd=3))
LISTEN    0         500                      *:17100                  *:*        users:(("mysqld",pid=636,fd=28))
LISTEN    0         500                      *:17101                  *:*        users:(("mysqld",pid=1266,fd=28))
LISTEN    0         500                      *:17102                  *:*        users:(("mysqld",pid=1895,fd=28))
LISTEN    0         4096                     *:15991                  *:*        users:(("vtgate",pid=2064,fd=16))
LISTEN    0         4096                     *:15000                  *:*        users:(("vtctld",pid=78,fd=10))
LISTEN    0         4096                     *:15001                  *:*        users:(("vtgate",pid=2064,fd=17))
LISTEN    0         4096                     *:15100                  *:*        users:(("vttablet",pid=680,fd=16))
LISTEN    0         4096                     *:15101                  *:*        users:(("vttablet",pid=1310,fd=15))
LISTEN    0         4096                     *:15102                  *:*        users:(("vttablet",pid=1939,fd=16))
LISTEN    0         4096                     *:15999                  *:*        users:(("vtctld",pid=78,fd=9))
LISTEN    0         4096                     *:16100                  *:*        users:(("vttablet",pid=680,fd=15))
LISTEN    0         4096                     *:16101                  *:*        users:(("vttablet",pid=1310,fd=14))
LISTEN    0         4096                     *:16102                  *:*        users:(("vttablet",pid=1939,fd=15))
LISTEN    0         4096                     *:15306                  *:*        users:(("vtgate",pid=2064,fd=14))
Daha sonra MySQL Linux'ta çalıştığı için tablo isimlerinin büyük küçük harf duyarlı olduğunu gördüm
Bunu değiştirmek için  normalde MySQL başlarken /etc/mysql/my.cnf dosyasında yapmak yeterli.
lower_case_table_names = 1
Ancak Vitess bu dosyayı okumuyor. Kendi ayarlarımı vermek için EXTRA_MY_CNF isimli bir değişkeni kullanmak gerekiyor. Bu yüzden run.sh şöyle oldu
#!/bin/bash
docker run --rm --name vitesslocal \
 -v /mnt/d/vitessrepo/vitess:/myvitess \
 -e EXTRA_MY_CNF=/myvitess/myvitess.cnf \
 -p 15306:15306  -p 15000:15000 -p 15001:15001 -p 15991:15991 -p 15999:15999 \
 -it vitess/local
myvitess.cnf dosyası şöyle
lower_case_table_names = 1
Sunucular
Bu komut "vitess/local" image'ımızı çalıştırır ve bazı tablolarla doldurur. Çalışan şeyler şöyle
$ ps -al
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S   999    18     1  1  80   0 - 2653497 futex_ pts/0  00:00:19 etcd
4 S   999    78     1  0  80   0 - 193940 futex_ pts/0   00:00:01 vtctld
4 S   999   160     1  0  80   0 -   597 do_wai pts/0    00:00:00 mysqld_safe
4 S   999   638   160  0  80   0 - 1174998 x64_sy pts/0  00:00:03 mysqld
4 S   999   682     1  0  80   0 - 209578 futex_ pts/0   00:00:03 vttablet
0 S   999   785     1  0  80   0 -   597 do_wai pts/0    00:00:00 mysqld_safe
0 S   999  1263   785  0  80   0 - 910514 x64_sy pts/0   00:00:04 mysqld
4 S   999  1307     1  0  80   0 - 209642 futex_ pts/0   00:00:02 vttablet
0 S   999  1414     1  0  80   0 -   597 do_wai pts/0    00:00:00 mysqld_safe
0 S   999  1892  1414  0  80   0 - 910514 x64_sy pts/0   00:00:04 mysqld
4 S   999  1936     1  0  80   0 - 209658 futex_ pts/0   00:00:02 vttablet
4 S   999  2061     1  0  80   0 - 189993 futex_ pts/0   00:00:01 vtgate
4 S   999  2085     1  0  80   0 -  1000 do_wai pts/0    00:00:00 bash
4 T   999  2098  2085  0  80   0 -  4495 do_sig pts/0    00:00:00 mysql
4 R   999  2113  2085  0  80   0 -  1889 -      pts/0    00:00:00 ps
vtgate sunucusu
Parametreleri şöyle. Burada mysql_auth_server_impl ile kullanıcı authentication olmadığı görülebilir.
ps -eo args | grep vtgate
vtgate -topo_implementation etcd2 
  -topo_global_server_address localhost:2379 
  -topo_global_root /vitess/global 
  -log_dir /vt/vtdataroot/tmp 
  -log_queries_to_file /vt/vtdataroot/tmp/vtgate_querylog.txt 
  -port 15001 
  -grpc_port 15991 
  -mysql_server_port 15306 
  -mysql_server_socket_path /tmp/mysql.sock 
  -cell zone1 -cells_to_watch zone1 
  -tablet_types_to_wait PRIMARY,REPLICA 
  -service_map grpc-vtgateservice 
  -pid_file /vt/vtdataroot/tmp/vtgate.pid 
  -mysql_auth_server_impl none 
  -mysql_server_version 8.0.17
Neticede : 
- zone1 isimli cell açar. 
- 3 tane tablet açar. Tabletlerin numarası 100,101 ve 102. Bu tabletlerden birisi master, diğeri replica, diğeri ise readonly. Yani şöyleler
type:PRIMARY
type:REPLICA 
type:RDONLY
commerce isimli bir keyspace yaratır. Bu keyspace içinde product, customer , corder isimli 3 tane tablo var
Detaylar 101_initial_cluster.sh isimli dosyada

vitess\examples\local\101_initial_cluster.sh
Önce topology server çalıştırılır. Şöyledir
# start topo server
if [ "${TOPO}" = "zk2" ]; then
  CELL=zone1 ./scripts/zk-up.sh
elif [ "${TOPO}" = "k8s" ]; then
  CELL=zone1 ./scripts/k3s-up.sh
else
  CELL=zone1 ./scripts/etcd-up.sh
fi
Daha sonra  vtctld komutu çalıştırılır. Yani topology sunucusuna Http arayüzü açılır. Şöyledir
# start vtctld
CELL=zone1 ./scripts/vtctld-up.sh
Daha sonra mysqlctl-up.sh içinde   mysqlctl komutu ile MySQL sunucusu başlatılır
Ayrıca vttablet-up.sh içinde vttablet komutu ile vttableletler başlatılır. Burada vttablelete keyspace veriliyor. Bundan sonra vttablet üzerinde yapılacak işlemler için bu keyspace kullanılır. Sanırım bir vttable tek keyspace'e hizmet edebiliyor. Suport multiple schemas with a single vttablet sorusu var ama cevap nedir anlamadım. Şöyledir
# start vttablets for keyspace commerce
for i in 100 101 102; do
  CELL=zone1 TABLET_UID=$i ./scripts/mysqlctl-up.sh
  CELL=zone1 KEYSPACE=commerce TABLET_UID=$i ./scripts/vttablet-up.sh
done
Tabletlerden 100 numaralı olan primary yapılır. Şöyledir
# set one of the replicas to primary
vtctldclient InitShardPrimary --force commerce/0 zone1-100
Veri tabanına schema verilir. Yani tablolar yaratılır. Şöyledir
# create the schema
vtctlclient ApplySchema -sql-file create_commerce_schema.sql commerce
vschema yaratılır. Bu adım mecburi mi bilmiyorum. Şöyledir
# create the vschema
vtctlclient ApplyVSchema -vschema_file vschema_commerce_initial.json commerce
vtgate başlatılır. Şöyledir
# start vtgate
CELL=zone1 ./scripts/vtgate-up.sh
Docker Terminal
Yeni docker terminal açmak için şöyle yaparız.
docker exec -it vitesslocal bash
MySQL
Docker dışından bağlanmak için şöyle yaparız
$ mysql -h 127.0.01 -P 15306 -u root
Örnek
İlk kayıt için şöyle yaparız
mysql commerce;
mysql> INSERT INTO product(sku,description,price) VALUES (1,2,3);
Ancak veri kalıcı değildir. docker tekrar başlayınca tüm tablolar boş gelir.

Move Tables Adımı
Şu scriptleri çalıştırırız. Bunları yapınca commerce altındaki tüm tablollar customer diye başka bir keyspace altına taşınır
201_customer_tablets.sh - tabletleri başlatır
202_move_tables.sh - Veriyi taşır
203_switch_reads.sh - Read'i yönlendirir
204_switch_writes.sh - Write'ı yönlendirir
205_clean_commerce.sh - commerce'i temizler
Not : commerce keyspace altındaki tabletler kapatılmıyor, halen çalışıyorlar. Yani 100,101,102, 200,201,202 tabletleri çalışıyor

Resharding Adımı
Şu scriptleri çalıştırırız
301_customer_sharded.sh - Yeni schema yaratır
302_new_shards.sh - tabletleri başlatır
303_reshard.sh - reshard'ı başlatır
304_switch_reads.sh
305_switch_writes.sh
306_down_shard_0.sh - 200 numaraları tabletleri siler
300,301,302,
400,401,402 tabletleri çalışıyor. Görüntü şöyle
İşte bu noktada şöyle yaparsak, MySQL Compatibility sayfasında belirtilen hatalardan birisini görebiliriz. Çünkü sharded ortamda Select içinde belirtilmeyen bir sütuna atıfta bulunarak order by yapmaya çalıştık. Daha detaylı bilgi için unsupported_cases dosyasına bakılabilir
mysql> select * from customer order by customer_id;
ERROR 1105 (HY000): unsupported: in scatter query: order by must reference a column
  in the select list: customer_id asc
Veri Tabanını Temizleme
Şöyle yaparız
mysql -Nse 'show tables' ADV | while read table; do mysql -e "SET FOREIGN_KEY_CHECKS=0; drop table \`$table\`" ADV; done
mysql -Nse 'show tables' ADV | while read table; do mysql -e "SET FOREIGN_KEY_CHECKS=0; drop view \`$table\`" ADV; done





Hiç yorum yok:

Yorum Gönder

CREATE EVENT - Scheduled Task İçindir

Örnek Şöyle yaparız CREATE EVENT myevent     ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR     DO       UPDATE myschema.mytable SET myc...