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