From 1f545e3bdd40c6e8e8f6b2e2bcd8e9f19da995ef Mon Sep 17 00:00:00 2001 From: <> Date: Thu, 13 Jun 2024 21:24:48 +0000 Subject: [PATCH] Deployed 9125e9dc with MkDocs version: 1.6.0 --- .nojekyll | 0 404.html | 1979 +++++ .../Uptime SLA/index.html | 2338 ++++++ .../index.html | 2161 ++++++ .../MariaDB Enterprise Backup/index.html | 2941 ++++++++ Backup and Restore/index.html | 2865 +++++++ Billing and Power Tier/Billing/index.html | 2155 ++++++ Billing and Power Tier/index.html | 2093 +++++ Configure your Database Server(s)/index.html | 2635 +++++++ .../Connect from Java App/index.html | 2209 ++++++ .../Connect from MongoDB clients/index.html | 2075 +++++ .../Connect from Node js App/index.html | 2337 ++++++ .../Connect from Python App/index.html | 2396 ++++++ .../index.html" | 2476 ++++++ .../index.html" | 2157 ++++++ .../Connect using Connector R2DBC/index.html | 2122 ++++++ .../Connect using MariaDB CLI | 144 + .../Connect using ODBC/index.html | 2880 +++++++ Connecting to Sky DBs/connect_window.png | Bin 0 -> 221887 bytes Connecting to Sky DBs/index.html | 2191 ++++++ Connecting to Sky DBs/wodbc1.png | Bin 0 -> 42940 bytes Connecting to Sky DBs/wodbc2.png | Bin 0 -> 53719 bytes Connecting to Sky DBs/wodbc3.png | Bin 0 -> 44548 bytes .../Import CSV data/index.html | 2266 ++++++ .../Import data from external DB/index.html | 2226 ++++++ .../Install Mariadb-dump/index.html | 2193 ++++++ .../Install mariadb-import/index.html | 2191 ++++++ .../index.html | 2122 ++++++ .../index.html | 2214 ++++++ Data loading, Migration/index.html | 2050 +++++ .../index.html | 2399 ++++++ Data offloading/index.html | 2134 ++++++ FAQs/index.html | 4313 +++++++++++ FractionalDBA/index.html | 2264 ++++++ Portal features/Launch page/index.html | 2110 ++++++ .../Manage your Service/index.html | 2159 ++++++ Portal features/Notifications/index.html | 2133 ++++++ .../Service Details page/index.html | 2086 +++++ .../Service Monitoring Panels/index.html | 3795 ++++++++++ Portal features/index.html | 2342 ++++++ .../Launch DB using the REST API/index.html | 2483 ++++++ .../index.html | 2938 ++++++++ Quickstart/Untitled 1.png | Bin 0 -> 298002 bytes Quickstart/Untitled.png | Bin 0 -> 196661 bytes Quickstart/index.html | 2243 ++++++ .../Instance Size Choices/index.html | 2597 +++++++ Reference Guide/MaxScale Reference/index.html | 3695 +++++++++ .../Monitoring Metrics Reference/index.html | 3846 ++++++++++ Reference Guide/REST API Reference/index.html | 2059 +++++ Reference Guide/Region Choices/index.html | 2273 ++++++ .../Sky Stored Procedures/index.html | 2564 +++++++ Reference Guide/index.html | 2153 ++++++ Scaling horizontally, HA/index.html | 2059 +++++ Security/Configuring Firewall/index.html | 2224 ++++++ Security/Managing API keys/index.html | 2152 ++++++ Security/Managing Portal Users/index.html | 2238 ++++++ Security/Portal Single Sign-On/index.html | 2135 ++++++ Security/Private VPC connections/index.html | 2058 +++++ Security/index.html | 2056 +++++ .../Setting up AWS Private Link/index.html | 2642 +++++++ .../index.html | 2737 +++++++ .../index.html | 2052 +++++ architecture.png | Bin 0 -> 413992 bytes assets/favicon.png | Bin 0 -> 30390 bytes assets/images/favicon.png | Bin 0 -> 1870 bytes assets/javascripts/bundle.ad660dcc.min.js | 29 + assets/javascripts/bundle.ad660dcc.min.js.map | 7 + assets/javascripts/lunr/min/lunr.ar.min.js | 1 + assets/javascripts/lunr/min/lunr.da.min.js | 18 + assets/javascripts/lunr/min/lunr.de.min.js | 18 + assets/javascripts/lunr/min/lunr.du.min.js | 18 + assets/javascripts/lunr/min/lunr.el.min.js | 1 + assets/javascripts/lunr/min/lunr.es.min.js | 18 + assets/javascripts/lunr/min/lunr.fi.min.js | 18 + assets/javascripts/lunr/min/lunr.fr.min.js | 18 + assets/javascripts/lunr/min/lunr.he.min.js | 1 + assets/javascripts/lunr/min/lunr.hi.min.js | 1 + assets/javascripts/lunr/min/lunr.hu.min.js | 18 + assets/javascripts/lunr/min/lunr.hy.min.js | 1 + assets/javascripts/lunr/min/lunr.it.min.js | 18 + assets/javascripts/lunr/min/lunr.ja.min.js | 1 + assets/javascripts/lunr/min/lunr.jp.min.js | 1 + assets/javascripts/lunr/min/lunr.kn.min.js | 1 + assets/javascripts/lunr/min/lunr.ko.min.js | 1 + assets/javascripts/lunr/min/lunr.multi.min.js | 1 + assets/javascripts/lunr/min/lunr.nl.min.js | 18 + assets/javascripts/lunr/min/lunr.no.min.js | 18 + assets/javascripts/lunr/min/lunr.pt.min.js | 18 + assets/javascripts/lunr/min/lunr.ro.min.js | 18 + assets/javascripts/lunr/min/lunr.ru.min.js | 18 + assets/javascripts/lunr/min/lunr.sa.min.js | 1 + .../lunr/min/lunr.stemmer.support.min.js | 1 + assets/javascripts/lunr/min/lunr.sv.min.js | 18 + assets/javascripts/lunr/min/lunr.ta.min.js | 1 + assets/javascripts/lunr/min/lunr.te.min.js | 1 + assets/javascripts/lunr/min/lunr.th.min.js | 1 + assets/javascripts/lunr/min/lunr.tr.min.js | 18 + assets/javascripts/lunr/min/lunr.vi.min.js | 1 + assets/javascripts/lunr/min/lunr.zh.min.js | 1 + assets/javascripts/lunr/tinyseg.js | 206 + assets/javascripts/lunr/wordcut.js | 6708 +++++++++++++++++ .../workers/search.b8dbb3d2.min.js | 42 + .../workers/search.b8dbb3d2.min.js.map | 7 + assets/sky_logo.png | Bin 0 -> 66591 bytes assets/sky_logo2.png | Bin 0 -> 30390 bytes assets/stylesheets/main.6543a935.min.css | 1 + assets/stylesheets/main.6543a935.min.css.map | 1 + assets/stylesheets/palette.06af60db.min.css | 1 + .../stylesheets/palette.06af60db.min.css.map | 1 + extra.css | 6 + index.html | 2296 ++++++ search/search_index.json | 1 + sitemap.xml | 3 + sitemap.xml.gz | Bin 0 -> 127 bytes stylesheets/extra.css | 6 + 115 files changed, 139957 insertions(+) create mode 100644 .nojekyll create mode 100644 404.html create mode 100644 Autonomously scale Compute, Storage/Uptime SLA/index.html create mode 100644 Autonomously scale Compute, Storage/index.html create mode 100644 Backup and Restore/MariaDB Enterprise Backup/index.html create mode 100644 Backup and Restore/index.html create mode 100644 Billing and Power Tier/Billing/index.html create mode 100644 Billing and Power Tier/index.html create mode 100644 Configure your Database Server(s)/index.html create mode 100644 Connecting to Sky DBs/Connect from Java App/index.html create mode 100644 Connecting to Sky DBs/Connect from MongoDB clients/index.html create mode 100644 Connecting to Sky DBs/Connect from Node js App/index.html create mode 100644 Connecting to Sky DBs/Connect from Python App/index.html create mode 100644 "Connecting to Sky DBs/Connect from \342\200\230C++\342\200\231 App/index.html" create mode 100644 "Connecting to Sky DBs/Connect from \342\200\230C\342\200\231 App/index.html" create mode 100644 Connecting to Sky DBs/Connect using Connector R2DBC/index.html create mode 100644 Connecting to Sky DBs/Connect using MariaDB CLI create mode 100644 Connecting to Sky DBs/Connect using ODBC/index.html create mode 100644 Connecting to Sky DBs/connect_window.png create mode 100644 Connecting to Sky DBs/index.html create mode 100644 Connecting to Sky DBs/wodbc1.png create mode 100644 Connecting to Sky DBs/wodbc2.png create mode 100644 Connecting to Sky DBs/wodbc3.png create mode 100644 Data loading, Migration/Import CSV data/index.html create mode 100644 Data loading, Migration/Import data from external DB/index.html create mode 100644 Data loading, Migration/Install Mariadb-dump/index.html create mode 100644 Data loading, Migration/Install mariadb-import/index.html create mode 100644 Data loading, Migration/Migrating your existing Production DB/index.html create mode 100644 Data loading, Migration/Replicating data from external DB/index.html create mode 100644 Data loading, Migration/index.html create mode 100644 Data offloading/Replicating data from SkySQL to external database/index.html create mode 100644 Data offloading/index.html create mode 100644 FAQs/index.html create mode 100644 FractionalDBA/index.html create mode 100644 Portal features/Launch page/index.html create mode 100644 Portal features/Manage your Service/index.html create mode 100644 Portal features/Notifications/index.html create mode 100644 Portal features/Service Details page/index.html create mode 100644 Portal features/Service Monitoring Panels/index.html create mode 100644 Portal features/index.html create mode 100644 Quickstart/Launch DB using the REST API/index.html create mode 100644 Quickstart/Launch DB using the Terraform Provider/index.html create mode 100644 Quickstart/Untitled 1.png create mode 100644 Quickstart/Untitled.png create mode 100644 Quickstart/index.html create mode 100644 Reference Guide/Instance Size Choices/index.html create mode 100644 Reference Guide/MaxScale Reference/index.html create mode 100644 Reference Guide/Monitoring Metrics Reference/index.html create mode 100644 Reference Guide/REST API Reference/index.html create mode 100644 Reference Guide/Region Choices/index.html create mode 100644 Reference Guide/Sky Stored Procedures/index.html create mode 100644 Reference Guide/index.html create mode 100644 Scaling horizontally, HA/index.html create mode 100644 Security/Configuring Firewall/index.html create mode 100644 Security/Managing API keys/index.html create mode 100644 Security/Managing Portal Users/index.html create mode 100644 Security/Portal Single Sign-On/index.html create mode 100644 Security/Private VPC connections/index.html create mode 100644 Security/index.html create mode 100644 Using AWS GCP private VPC connections/Setting up AWS Private Link/index.html create mode 100644 Using AWS GCP private VPC connections/Setting up GCP Private Service Connect/index.html create mode 100644 Using AWS GCP private VPC connections/index.html create mode 100644 architecture.png create mode 100644 assets/favicon.png create mode 100644 assets/images/favicon.png create mode 100644 assets/javascripts/bundle.ad660dcc.min.js create mode 100644 assets/javascripts/bundle.ad660dcc.min.js.map create mode 100644 assets/javascripts/lunr/min/lunr.ar.min.js create mode 100644 assets/javascripts/lunr/min/lunr.da.min.js create mode 100644 assets/javascripts/lunr/min/lunr.de.min.js create mode 100644 assets/javascripts/lunr/min/lunr.du.min.js create mode 100644 assets/javascripts/lunr/min/lunr.el.min.js create mode 100644 assets/javascripts/lunr/min/lunr.es.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.he.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hu.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hy.min.js create mode 100644 assets/javascripts/lunr/min/lunr.it.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ja.min.js create mode 100644 assets/javascripts/lunr/min/lunr.jp.min.js create mode 100644 assets/javascripts/lunr/min/lunr.kn.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ko.min.js create mode 100644 assets/javascripts/lunr/min/lunr.multi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.nl.min.js create mode 100644 assets/javascripts/lunr/min/lunr.no.min.js create mode 100644 assets/javascripts/lunr/min/lunr.pt.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ro.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ru.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sa.min.js create mode 100644 assets/javascripts/lunr/min/lunr.stemmer.support.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sv.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ta.min.js create mode 100644 assets/javascripts/lunr/min/lunr.te.min.js create mode 100644 assets/javascripts/lunr/min/lunr.th.min.js create mode 100644 assets/javascripts/lunr/min/lunr.tr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.vi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.zh.min.js create mode 100644 assets/javascripts/lunr/tinyseg.js create mode 100644 assets/javascripts/lunr/wordcut.js create mode 100644 assets/javascripts/workers/search.b8dbb3d2.min.js create mode 100644 assets/javascripts/workers/search.b8dbb3d2.min.js.map create mode 100644 assets/sky_logo.png create mode 100644 assets/sky_logo2.png create mode 100644 assets/stylesheets/main.6543a935.min.css create mode 100644 assets/stylesheets/main.6543a935.min.css.map create mode 100644 assets/stylesheets/palette.06af60db.min.css create mode 100644 assets/stylesheets/palette.06af60db.min.css.map create mode 100644 extra.css create mode 100644 index.html create mode 100644 search/search_index.json create mode 100644 sitemap.xml create mode 100644 sitemap.xml.gz create mode 100644 stylesheets/extra.css diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/404.html b/404.html new file mode 100644 index 00000000..bc2a7be7 --- /dev/null +++ b/404.html @@ -0,0 +1,1979 @@ + + + +
+ + + + + + + + + + + + + + +MariaDB SkySQL customers should assess the availability requirements of their application and choose an appropriate service tier to meet their objectives. MariaDB SkySQL customers are on the Foundation Tier unless they have specifically purchased and paid for Power Tier service.
+Tier | +Performance Standard | +
---|---|
SkySQL Foundation Tier | +ā¢ Multi-node configurations will deliver a 99.95% service availability on a per-billing-month basis. | +
ā¢ For example, with this availability target in a 30 day calendar month the maximum service downtime is 21 minutes and 54 seconds. | ++ |
SkySQL Power Tier | +ā¢ Multi-node configurations will deliver a 99.995% service availability on a per-billing-month basis. | +
ā¢ For example, with this availability target in a 30 day calendar month the maximum service downtime is 2 minutes and 11 seconds. | ++ |
Service DowntimeĀ is measured at each SkySQL database endpoint as the total number of full minutes, outside of scheduled downtime for maintenance and upgrades, where continuous attempts to establish a connection within the minute fail as reflected in minute-by-minute logs.
+Monthly Uptime PercentageĀ is calculated on a per-billing-month basis as the total number of minutes in a month, minus the number of minutes of measuredĀ Service DowntimeĀ within the month, divided by the number of minutes in that month. When a service is deployed for only part of a month, it is assumed to be 100% available for the portion of the month that it is not deployed.
+Service CreditĀ is the percentage of the total fees paid by you for a given SkySQL service during the month in which the downtime occurred to be credited if MariaDB approves your claim. The percentage used in calculating Service Credit is dependent on whether the customer is on Foundation Tier or Power Tier, and is dependent on the calculatedĀ Monthly Uptime Percentage.
+Tier | +Monthly Uptime Percentage | +Percentage Applied | +
---|---|---|
Foundation Tier | +Less than 99.95%, but greater than or equal to 99.0% | +10% | +
Foundation Tier | +Less than 99.0% | +25% | +
Power Tier | +Less than 99.995%, but greater than or equal to 99.0% | +10% | +
Power Tier | +Less than 99.0% | +25% | +
MariaDB will grant and process claims, provided the customer has satisfied itsĀ Customer ObligationsĀ and that none of theĀ ExclusionsĀ listed apply to the claim.Ā Service CreditsĀ will be issued only upon request within 60 days of the end of the billing period of the month of impact to service availability, and upon confirmation of outage.Ā Service CreditsĀ will be issued in the form of a monetary credit applied to future use of the service that experienced theĀ Service Downtime.Ā Service CreditsĀ will not be applied to fees for any other SkySQL instance.
+The aggregate maximum number ofĀ Service CreditsĀ to be issued by MariaDB to customers for any and allĀ Service DowntimeĀ that occurs in a single billing month will not exceed 50% of the amount due from the customer for the covered service for the applicable month.
+A customer will forfeit their right to receive aĀ Service CreditĀ unless they:
+Out-of-scope configurations
+TheĀ Performance StandardĀ does not apply to single instance SkySQL service configuration or services in Technical Preview. Customers requiring High Availability should deploy instead in production-ready multi-node service configuration.
+See "Choose a SkySQL Release" for information on SkySQL services in Technical Preview.
+Underlying infrastructure
+Impact to service availability caused by availability or performance of cloud services used to operate MariaDB SkySQL is excluded. This includes any such outages in Amazon Web Services (AWS) and Amazon Elastic Kubernetes Service (EKS), and Google Cloud Platform (GCP) and Google Kubernetes Engine (GKE).
+Network interruption
+Impact to service availability caused by blocking of network traffic by ISPs, network providers, governments, or third parties is excluded.
+External factors
+Impact to your use of service based on factors outside MariaDB SkySQL are excluded. This includes periods of downtime for your applications.
+Uncorroborated impacts
+Only impacts to service availability detected atĀ point of measurementĀ are subject when determining the uptime percentage. Service availability impacts measured through any other means, such as application instrumentation, are excluded except as also measured asĀ Service DowntimeĀ by MariaDB.
+Portal access
+Impact to your ability to access or use the MariaDB SkySQL portal, an interface provided to manage services, is excluded. This includes any component and content linked from the MariaDB SkySQL portal, including Documentation, the Customer Support portal, Monitoring, and Workload Analysis. These components operate independently from database services and do not impact database availability.
+Resource usage
+Impact to service availability caused by usage of system resources, such as problems caused by excessive workload consumption of CPU, disk I/O, disk capacity, memory, and other system resources, are excluded.
+Clients and connectors
+Impact to service availability caused by the use of unsupported third-party clients and connectors is excluded.
+Non-paying customers
+TheĀ Performance StandardĀ applies only to paying MariaDB SkySQL customers who are paid-in-full. All other MariaDB SkySQL customers, including those not paid-in-full and those customers participating in a free or credited service trial, are excluded.
+Customer-directed maintenance
+When a customer directs that MariaDB conduct a maintenance operation on a service, any resulting impact to service availability is excluded.
+Customer-approved maintenance
+When a customer approves MariaDB-recommended maintenance on a service, any resulting impact to service availability is excluded.
+Customer-initiated changes
+When a customer initiates changes to their SkySQL services, e.g., via access to the database or via the SkySQL portal, any resulting impact to service availability is excluded.
+Initial provisioning
+Availability of services during initial provisioning, e.g., before a service becomes online, healthy, and available, is excluded.
+Autonomous features enable automatic scaling in response to changes in workload.
+Auto-scale of nodes enables scaling based on load:
+Auto-scale of storage enables expansion of capacity based on usage.
+Autonomous features can be enabled at time ofĀ service launch. Autonomous features can be enabled or disabled after launch.
+ +Auto-scaling of nodes can be enabled either at time of service launch or after service launch.
+DuringĀ service launch:
+After service launch,Ā manage Autonomous settings, and enable the desired auto-scaling features.
+Auto-scaling of storage can be enabled either at time of service launch or after service launch.
+DuringĀ Service Launch:
+After service launch,Ā manage Autonomous settings, and enable the desired auto-scaling features.
+For ColumnStore Data Warehouse, object storage adjusts automatically. Autonomous scaling features for storage are not used by this topology.
+To manage Autonomous settings:
+Automatic scaling occurs based on rules.
+Policy | +Condition | +Action | +
---|---|---|
Auto-Scale Disk | +Disk utilization > 90% sustained for 5 minutes. The disk is expected to run out of capacity in the next 24 hours (predicted based on the last 6 hours of service usage). |
+Upgrade storage to the next available size in 100GB increments. Note: you cannot downgrade storage, the upgrade is irreversible |
+
Auto-Scale Nodes Out | +CPU utilization > 75% over all replicas sustained for 30 minutes. Number of concurrent sessions > 90% over all replicas sustained for 1 hour. Number of concurrent sessions is expected to hit the maximum within 4 hours (predicted based on the last 2 hours of service usage) |
+Add new replica or node Additional nodes will be of the same size and configuration as existing nodes | +
Auto-Scale Nodes In | +CPU utilization < 50% over all replicas sustained for 1 hour. Number of concurrent sessions < 50% over all replicas sustained for 1 hour |
+Remove replica or node Node count will not decrease below the initial count set at launch | +
Auto-Scale Nodes Up | +Number of concurrent sessions is expected to hit the maximum within 4 hours (predicted based on the last 2 hours of service usage) | +Upgrade all nodes to the next available size | +
Auto-Scale Nodes Down | +CPU utilization < 50% over all replicas sustained for 1 hour. Number of concurrent sessions < 50% over all replicas sustained for 1 hour |
+Downgrade nodes Node size will not decrease below the initial node size set at launch | +
Autonomous actions are not instantaneous.
+Cooldown periods may apply. A cooldown period is the time period after a scaling operation is completed before another scaling operation can occur. The cooldown period for storage scaling is 6 hours.
+ + + + + + + + + + + + + + +Regular and reliable backups are essential to successful recovery of mission critical applications.Ā MariaDB Enterprise ServerĀ backup and restore operations are performed usingĀ MariaDB Enterprise Backup, anĀ enterprise-buildĀ ofĀ MariaDB Backup.
+MariaDB Enterprise BackupĀ is compatible with MariaDB Enterprise Server 10.2, 10.3, 10.4, 10.5, and 10.6.
+MariaDB Enterprise Backup creates a file-level backup of data from the MariaDB Enterprise Server data directory. This backup includesĀ temporal data, and the encrypted and unencrypted tablespaces of supported storage engines (e.g.,Ā InnoDB,Ā MyRocks,Ā Aria).
+MariaDB Enterprise Server implements:
+Backup support is specific to storage engines. All supported storage engines enable full backup. The InnoDB storage engine additionally supports incremental backup.
+A feature of MariaDB Enterprise Backup and MariaDB Enterprise Server, non-blocking backups minimize workload impact during backups. When MariaDB Enterprise Backup connects to MariaDB Enterprise Server, staging operations are initiated to protect data during read.
+Non-blocking backup functionality differs from historical backup functionality in the following ways:
+FLUSHĀ TABLESĀ WITHĀ READĀ LOCK
, which closed open tables and only allowed tables to be reopened with a read lock during the duration of backups.MariaDB Enterprise Backup creates complete or incremental backups of MariaDB Enterprise Server data, and is also used to restore data from backups produced using MariaDB Enterprise Backup.
+Full backups produced using MariaDB Enterprise Server are not initially point-in-time consistent, and an attempt to restore from a raw full backup will cause InnoDB to crash to protect the data.
+Incremental backups produced using MariaDB Enterprise Backup contain only the changes since the last backup and cannot be used standalone to perform a restore.
+To restore from a backup, you first need to prepare the backup for point-in-time consistency using theĀ --prepare
Ā command:
-prepare
Ā command on aĀ full backupĀ synchronizes the tablespaces, ensuring that they are point-in-time consistent and ready for use in recovery.-prepare
Ā command on anĀ incremental backupĀ synchronizes the tablespaces and also applies the updated data into the previous full backup, making it a complete backup ready for use in recovery.-prepare
Ā command on data that is to be used for aĀ partial restoreĀ (when restoring only one or more selected tables) requires that you also use theĀ -export
Ā option to create the necessaryĀ .cfg
Ā files to use in recovery.When MariaDB Enterprise Backup restores from a backup, it copies or moves the backup files into the MariaDB Enterprise Server data directory, as defined by theĀ datadir
Ā system variable.
For MariaDB Enterprise Backup to safely restore data from full and incremental backups, the data directory must be empty. One way to achieve this is to move the data directory aside to a unique directory name:
+/var/lib/mysql-2020-01-01
)Ā ORĀ remove the old data directory (depending on how much space you have available).mkdirĀ /var/lib/mysql
).chownĀ -RĀ mysql:mysqlĀ /var/lib/mysql
).When MariaDB Enterprise Backup performs a backup operation, it not only copies files from the data directory but also connects to the running MariaDB Enterprise Server.
+This connection to MariaDB Enterprise Server is used to manage locks and backup staging that prevent the Server from writing to a file while being read for a backup.
+MariaDB Enterprise Backup establishes this connection based on the user credentials specified with theĀ --user
Ā andĀ --password
Ā options when performing a backup.
It is recommended that a dedicated user be created and authorized to perform backups.
+MariaDB Enterprise Backup 10.5 and later requires this user to have theĀ RELOAD
,Ā PROCESS
,Ā LOCKĀ TABLES
, andĀ BINLOGĀ MONITOR
Ā privileges. (TheĀ BINLOG MONITORĀ privilege replaced theĀ REPLICATIONĀ CLIENT
Ā privilege in MariaDB Enterprise Server 10.5.):
**CREATE** **USER** 'mariabackup'@'localhost'IDENTIFIED **BY** 'mbu_passwd'**;GRANT** RELOAD**,** PROCESS**,** **LOCK** TABLES**,** BINLOG MONITOR**ON** ***.*****TO** 'mariabackup'@'localhost'**;**
In the above example, MariaDB Enterprise Backup would run on the local system that runs MariaDB Enterprise Server. Where backups may be run against a remote server, the user authentication and authorization should be adjusted.
+While MariaDB Enterprise Backup requires a user for backup operations, no user is required for restore operations since restores occur while MariaDB Enterprise Server is not running.
+MariaDB Enterprise Backup 10.4 and earlier requires this user to have theĀ RELOAD
,Ā PROCESS
,Ā LOCKĀ TABLES
, andĀ REPLICATIONĀ CLIENT
Ā privileges. (TheĀ BINLOG MONITORĀ privilege replaced theĀ REPLICATIONĀ CLIENT
Ā privilege in MariaDB Enterprise Server 10.5.):
**CREATE** **USER** 'mariabackup'@'localhost'IDENTIFIED **BY** 'mbu_passwd'**;GRANT** RELOAD**,** PROCESS**,** **LOCK** TABLES**,** REPLICATION CLIENT**ON** ***.*****TO** 'mariabackup'@'localhost'**;**
In the above example, MariaDB Enterprise Backup would run on the local system that runs MariaDB Enterprise Server. Where backups may be run against a remote server, the user authentication and authorization should be adjusted.
+While MariaDB Enterprise Backup requires a user for backup operations, no user is required for restore operations since restores occur while MariaDB Enterprise Server is not running.
+Full backups performed with MariaDB Enterprise Backup contain all table data present in the database.
+When performing a full backup, MariaDB Enterprise Backup makes a file-level copy of the MariaDB Enterprise Server data directory. This backup omits log data such as the binary logs (binlog), error logs, general query logs, and slow query logs.
+When you perform a full backup, MariaDB Enterprise Backup writes the backup to theĀ --target-dir
Ā path. The directory must be empty or non-existent and the operating system user account must have permission to write to that directory. A database user account is required to perform the backup.
The version ofĀ mariabackup
Ā orĀ mariadb-backup
Ā should be the same version as the MariaDB Enterprise Server version. When the version does not match the server version, errors can sometimes occur, or the backup can sometimes be unusable.
To create a backup, executeĀ mariabackup
Ā orĀ mariadb-backup
Ā with theĀ [--backup](https://mariadb.com/docs/server/ref/mdb/cli/mariadb-backup/backup/)
Ā option, and provide the database user account credentials using theĀ [--user](https://mariadb.com/docs/server/ref/mdb/cli/mariadb-backup/user/)
Ā andĀ [--password](https://mariadb.com/docs/server/ref/mdb/cli/mariadb-backup/password/)
Ā options:
$ sudo mariabackup --backup \ --target-dir=/data/backups/full \ --user=mariabackup \ --password=mbu_passwd
Subsequent to the above example, the backup is now available in the designatedĀ --target-dir
Ā path.
A raw full backup is notĀ point-in-time consistentĀ and must be prepared before it can be used for a restore. The backup can be prepared any time after the backup is created and before the backup is restored. However, MariaDB recommends preparing a backup immediately after taking the backup to ensure that the backup is consistent.
+The backup should be prepared with the same version of MariaDB Enterprise Backup that was used to create the backup.
+To prepare the backup, executeĀ mariabackup
Ā orĀ mariadb-backup
Ā with theĀ [--prepare](https://mariadb.com/docs/server/ref/mdb/cli/mariadb-backup/prepare/)
Ā option:
$ sudo mariabackup --prepare \ --use-memory=34359738368 \ --target-dir=/data/backups/full
For best performance, theĀ [--use-memory](https://mariadb.com/docs/server/ref/mdb/cli/mariadb-backup/use-memory/)
Ā option should be set to the server'sĀ [innodb_buffer_pool_size](https://mariadb.com/docs/server/ref/mdb/system-variables/innodb_buffer_pool_size/)
Ā value.
Once a full backup has beenĀ preparedĀ to be point-in-time consistent, MariaDB Enterprise Backup is used to copy backup data to the MariaDB Enterprise Server data directory.
+To restore from a full backup:
+Restore from the "full" directory using theĀ -copy-back
Ā option:
$ sudo mariabackup --copy-back --target-dir=/data/backups/full
MariaDB Enterprise Backup writes to the data directory as the current user, which can be changed usingĀ sudo
. To confirm that restored files are properly owned by the user that runs MariaDB Enterprise Server, run a command like this (adapted for the correct user/group):
$ sudo chown -R mysql:mysql /var/lib/mysql
Once this is done, start MariaDB Enterprise Server:
+$ sudo systemctl start mariadb
When the Server starts, it works from the restored data directory.
+Full backups of large data-sets can be time-consuming and resource-intensive. MariaDB Enterprise Backup supports the use of incremental backups to minimize this impact.
+While full backups are resource-intensive at time of backup, the resource burden around incremental backups occurs when preparing for restore. First, the full backup is prepared for restore, then each incremental backup is applied.
+When you perform an incremental backup, MariaDB Enterprise Backup compares a previous full or incremental backup to what it finds on MariaDB Enterprise Server. It then creates a new backup containing the incremental changes.
+Incremental backup is supported for InnoDB tables. Tables using other storage engines receive full backups even during incremental backup operations.
+To increment a full backup, use theĀ --incremental-basedir
Ā option to indicate the path to the full backup and theĀ --target-dir
Ā option to indicate where you want to write the incremental backup:
$ sudo mariabackup --backup \ --incremental-basedir=/data/backups/full \ --target-dir=/data/backups/inc1 \ --user=mariabackup \ --password=mbu_passwd
In this example, MariaDB Enterprise Backup reads theĀ /data/backups/full
Ā directory, and MariaDB Enterprise Server then creates an incremental backup in theĀ /data/backups/inc1
Ā directory.
An incremental backup must be applied to a prepared full backup before it can be used in a restore operation. If you have multiple full backups to choose from, pick the nearest full backup prior to the incremental backup that you want to restore. You may also want to back up your full-backup directory, as it will be modified by the updates in the incremental data.
+If your full backup directory is not yet prepared, run this to make it consistent:
+$ sudo mariabackup --prepare --target-dir=/data/backups/full
Then, using the prepared full backup, apply the first incremental backup's data to the full backup in an incremental preparation step:
+$ sudo mariabackup --prepare \ --target-dir=/data/backups/full \ --incremental-dir=/data/backups/inc1
Once the incremental backup has been applied to the full backup, the full backup directory contains the changes from the incremental backup (that is, theĀ inc1/
Ā directory). Feel free to removeĀ inc1/
Ā to save disk space.
Once you have prepared the full backup directory with all the incremental changes you need (as described above), stop the MariaDB Enterprise Server,Ā emptyĀ its data directory, and restore from the original full backup directory using theĀ --copy-back
Ā option:
$ sudo mariabackup --copy-back --target-dir=/data/backups/full
MariaDB Enterprise Backup writes files into the data directory using either the current user or root (in the case of a sudo operation), which may be different from the system user that runs the database. Run the following to recursively update the ownership of the restored files and directories:
+$ sudo chown -R mysql:mysql /var/lib/mysql
Then, start MariaDB Enterprise Server. When the Server starts, it works from the restored data directory.
+In a partial backup, MariaDB Enterprise Backup copies a specified subset of tablespaces from the MariaDB Enterprise Server data directory. Partial backups are useful in establishing a higher frequency of backups on specific data, at the expense of increased recovery complexity. In selecting tablespaces for a partial backup, please consider referential integrity.
+Command-line options can be used to narrow the set of databases or tables to be included within a backup:
+Option | +Description | +
---|---|
--databases | +List of databases to include | +
--databases-exclude | +List of databases to omit from the backup | +
--databases-file | +Path to file listing the databases to include | +
--tables | +List of tables to include | +
--tables-exclude | +List of tables to exclude | +
--tables-file | +Path to file listing the tables to include | +
For example, you may wish to produce a partial backup, which excludes a specific database:
+$ sudo mariabackup --backup \ --target-dir=/data/backups/part \ --user=mariabackup \ --password=mbu_passwd \ --database-exclude=test
Partial backups can also be incremental:
+$ sudo mariabackup --backup \ --incremental-basedir=/data/backups/part \ --target-dir=/data/backups/part_inc1 \ --user=mariabackup \ --password=mbu_passwd \ --database-exclude=test
As with full and incremental backups, partial backups are not point-in-time consistent. A partial backup must be prepared before it can be used for recovery.
+A partial restore can be performed from a full backup or partial backup.
+The preparation step for either partial or full backup restoration requires the use of transportable tablespaces for InnoDB. As such, each prepare operation requires theĀ --export
Ā option:
$ sudo mariabackup --prepare --export --target-dir=/data/backups/part
When using a partial incremental backup for restore, the incremental data must be applied to its prior partial backup data before its data is complete. If performing partial incremental backups, run the prepare statement again to apply the incremental changes onto the partial backup that served as the base.
+$ sudo mariabackup --prepare --export \ --target-dir=/data/backups/part \ --incremental-dir=/data/backups/part_inc1
Unlike full and incremental backups, you cannot restore partial backups directly using MariaDB Enterprise Backup. Further, as a partial backup does not contain a complete data directory, you cannot restore MariaDB Enterprise Server to a startable state solely with a partial backup.
+To restore from a partial backup, you need to prepare a table on the MariaDB Enterprise Server, then manually copy the files into the data directory.
+The details of the restore procedure depend on the characteristics of the table:
+As partial restores are performed while the server is running, not stopped, care should be taken to prevent production workloads during restore activity.
+Note
+You can also use data from a full backup in a partial restore operation if you have prepared the data using theĀ --export
Ā option as described above.
To restore a non-partitioned table from a backup, first create a new table on MariaDB Enterprise Server to receive the restored data. It should match the specifications of the table you're restoring.
+Be extra careful if the backup data is from a server with a different version than the restore server, as some differences (such as a differingĀ ROW_FORMAT
) can cause an unexpected result.
Create an empty table for the data being restored:
+**CREATE** **TABLE** test**.**address_book **(** id INT **PRIMARY** **KEY** AUTO_INCREMENT**,** name VARCHAR**(**255**),** email VARCHAR**(**255**));**
Modify the table to discard the tablespace:
+**ALTER** **TABLE** test**.**address_book DISCARD TABLESPACE**;**
You can copy (or move) the files for the table from the backup to the data directory:
+$ sudo cp /data/backups/part_inc1/test/address_book.* /var/lib/mysql/test
Use a wildcard to include both theĀ .ibd
Ā andĀ .cfg
Ā files. Then, change the owner to the system user running MariaDB Enterprise Server:
$ sudo chown mysql:mysql /var/lib/mysql/test/address_book.*
Lastly, import the new tablespace:
+**ALTER** **TABLE** test**.**address_book IMPORT TABLESPACE**;**
MariaDB Enterprise Server looks in the data directory for the tablespace you copied in, then imports it for use. If the table is encrypted, it also looks for the encryption key with the relevant key ID that the table data specifies.
+Repeat this step for every table you wish to restore.
+Restoring a partitioned table from a backup requires a few extra steps compared to restoring a non-partitioned table.
+To restore a partitioned table from a backup, first create a new table on MariaDB Enterprise Server to receive the restored data. It should match the specifications of the table you're restoring, including the partition specification.
+Be extra careful if the backup data is from a server with a different version than the restore server, as some differences (such as a differingĀ ROW_FORMAT
) can cause an unexpected result.
Create an empty table for the data being restored:
+**CREATE** **TABLE** test**.**students **(** id INT **NOT** **NULL** AUTO_INCREMENT**,** name VARCHAR**(**255**),** email VARCHAR**(**255**),** graduating_year **YEAR,** **PRIMARY** **KEY** **(**id**,** graduating_year**))** ENGINE = InnoDBPARTITION **BY** RANGE **(**graduating_year**)** **(** PARTITION p0 **VALUES** **LESS** **THAN** **(**2019**),** PARTITION p1 **VALUES** **LESS** **THAN** **MAXVALUE);**
Then create a second empty table matching the column specification, but without partitions. This will be your working table:
+**CREATE** **TABLE** test**.**students_work **ASSELECT** * **FROM** test**.**students **WHERE** **NULL;**
For each partition you want to restore, discard the working table's tablespace:
+**ALTER** **TABLE** test**.**students_work DISCARD TABLESPACE**;**
Then, copy the table files from the backup, using the new name:
+$ sudo cp /data/backups/part_inc1/test/students.ibd /var/lib/mysql/test/students_work.ibd
+$ sudo cp /data/backups/part_inc1/test/students.cfg /var/lib/mysql/test/students_work.cfg
Change the owner to that of the user running MariaDB Enterprise Server:
+$ sudo chown mysql:mysql /var/lib/mysql/test/students_work.*
Import the copied tablespace:
+**ALTER** **TABLE** test**.**students_work IMPORT TABLESPACE**;**
Lastly, exchange the partition, copying the tablespace from the working table into the partition file for the target table:
+**ALTER** **TABLE** test**.**students EXCHANGE PARTITION p0 **WITH** **TABLE** test**.**students_work**;**
Repeat the above process for each partition until you have them all exchanged into the target table. Then delete the working table, as it's no longer necessary:
+**DROP** **TABLE** test**.**students_work**;**
This restores a partitioned table.
+When restoring a table with a full-text search (FTS) index, InnoDB may throw a schema mismatch error.
+In this case, to restore the table, it is recommended to:
+.cfg
Ā file.For example, to restore tableĀ t1
Ā with FTS index from databaseĀ db1
:
In the MariaDB shell, drop the table you are going to restore:
+**DROP** **TABLE** **IF** **EXISTS** db1**.**t1**;**
Create an empty table for the data being restored:
+**CREATE** **TABLE** db1**.**t1**(**f1 CHAR**(**10**))** ENGINE=INNODB**;**
Modify the table to discard the tablespace:
+**ALTER** **TABLE** db1**.**t1 DISCARD TABLESPACE**;**
In the operating system shell, copy the table files from the backup to the data directory of the corresponding database:
+$ sudo cp /data/backups/part/db1/t1.* /var/lib/mysql/db1
Remove theĀ .cfg
Ā file from the data directory:
$ sudo rm /var/lib/mysql/db1/t1.cfg
Change the owner of the newly copied files to the system user running MariaDB Enterprise Server:
+$ sudo chown mysql:mysql /var/lib/mysql/db1/t1.*
In the MariaDB shell, import the copied tablespace:
+**ALTER** **TABLE** db1**.**t1 IMPORT TABLESPACE**;**
Verify that the data has been successfully restored:
+**SELECT** * **FROM** db1**.**t1**;**
+--------+
+| f1 |
++--------+
+| ABC123 |
++--------+
Add the necessary secondary indexes:
+**ALTER** **TABLE** db1**.**t1 **FORCE,** **ADD** FULLTEXT **INDEX** f_idx**(**f1**);**
The table is now fully restored:
+**SHOW** **CREATE** **TABLE** db1**.**t1**\G**
*************************** 1. row ***************************
+ Table: t1
+Create Table: CREATE TABLE `t1` (
+ `f1` char(10) DEFAULT NULL,
+ FULLTEXT KEY `f_idx` (`f1`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
+
Recovering from a backup restores the data directory at a specific point-in-time, but it does not restore the binary log. In a point-in-time recovery, you begin by restoring the data directory from a full or incremental backup, then use theĀ mysqlbinlog
Ā utility to recover the binary log data to a specific point in time.
First, prepare the backup as you normally would for aĀ fullĀ orĀ incrementalĀ backup:
+$ sudo mariabackup --prepare --target-dir=/data/backups/full
When MariaDB Enterprise Backup runs on a MariaDB Enterprise Server where binary logs is enabled, it stores binary log information in theĀ xtrabackup_binlog_info
Ā file. Consult this file to find the name of the binary log position to use. In the following example, the log position isĀ 321
.
`$ sudo cat /data/backups/full/xtraback_binlog_info
+mariadb-node4.00001 321`
+Update the configuration file to use a new data directory.
+**[mysqld]**datadir=/var/lib/mysql_new
Using MariaDB Enterprise Backup, restore from the backup to the new data directory:
+$ sudo mariabackup --copy-back --target-dir=/data/backups/full
Then change the owner to the MariaDB Enterprise Server system user:
+$ sudo chown -R mysql:mysql /var/lib/mysql_new
Start MariaDB Enterprise Server:
+$ sudo systemctl start mariadb
Using the binary log file in the old data directory, the start position in theĀ xtrabackup_binlog_info
Ā file, the date and time you want to restore to, and theĀ mysqlbinlog
Ā utility to create an SQL file with the binary log changes:
$ mysqlbinlog --start-position=321 \ --stop-datetime="2019-06-28 12:00:00" \ /var/lib/mysql/mariadb-node4.00001 \ > mariadb-binlog.sql
Lastly, run the binary log SQL to restore the databases:
+$ mysql -u root -p < mariadb-binlog.sql
The SkySQL Backup service provides comprehensive Backup and Restore features through a secure API. We extend the automated nightly backups with a number of self service features. You can automatically create and store backups of your databases to ensure additional data safety or provide a robust disaster recovery solution. The backups are stored on reliable and secure cloud storage, ensuring they are readily available when needed. The backup process is seamless and does not affect the performance of your databases. SkySQL also offers the flexibility to customize your backup schedule according to your specific needs.
+Here is the list of features offered:
+Automatic nightly backups : Automated nightly backups include a full backup of every database in the service.
+Secure On-demand or scheduled backups
+Full (physical) backups : Full backups create a complete backup of the database server into a new backup folder. It uses mariabackup under the hood. Physical backups are performed by copying the individual data files or directories and the fastest way to do a backup.
+Incremental backups : Incremental backups update a previous backup with whatever changes to the data have occurred since the backup.
+Logical backups : Logical backups consist of the SQL statements necessary to restore the data, such as CREATE DATABASE, CREATE TABLE and INSERT. This is done using mariadb-dump(https://mariadb.com/kb/en/mariadb-dump/) and is the most flexible way to perform a backup and restore, and a good choice when the data size is relatively small.
+Bring your own Bucket (BYOB) : you can backup or restore data to/from your own bucket in either GCP or AWS.
+Backup your binlogs : Binlogs record database changes (data modifications, table structure changes) in a sequential, binary format. You can preserve binlogs for setting up replication or to recover to a certain point-in-time.
+Point-in-time recovery : you can restore from a full or a logical backup and then use a binlog backup to restore to a point-in-time.
+Secure backup/restores : Control backup/restore privileges by granting roles to users in SkySQL.
+while the daily automated backups are included the use of this API will incur nominal additional charges. Please contact info@skysql.com for details.
+The following documentation describes the API for the SkySQL Backup Service. This can be used directly with any HTTP client.
+Note
+Please refer to the API docs (swagger) for the latest API. +The information below might be slightly outdated.
+To authenticate with the API, do the following:
+Go to SkySQL API Key management page: https://app.skysql.com/user-profile/api-keys and generate an API key
+Export the value from the token field to an environment variable $API_KEY
+Use it on subsequent request, e.g:
+ curl --request GET 'https://api.skysql.com/skybackup/v1/backups/schedules' \\
+ --header "X-API-Key: ${API_KEY}"
+
Backups on large data sets can take time. You instruct the creation of a backup using a "schedule". You can either schedule a one-time backup (schedule now) or set up automatic backups using a cron schedule. A backup schedule results in a backup job which can be tracked using the status API. We support the following types of backups : full(physical), incremental(physical), binary log, and dump(logical).
+To create a backup schedule, you need to have the "administrator" role. You can add members and configure roles using the SkySQL portal.
+To create a full backup you need to make the following API call:
+curl --location 'https://api.skysql.com/skybackup/v1/backups/schedules' \
+--header 'Content-Type: application/json' \
+--header 'Accept: application/json' \
+--header 'X-API-Key: ${API_KEY}' \
+--data '{
+ "backup_type": "full",
+ "schedule": "once",
+ "service_id": "dbtgf28044362"
+}'
+
++note that each launched database is tracked with a service ID in SkySQL. You can fetch the service ID from the Fully qualified domain name(FQDN) of your service. For instance in dbpgf17106534.sysp0000.db2.skysql.com, 'dbpgf17106534' is the service ID. +You will find the FQDN in the Connect window
+
Typical API server response should look like:
+{
+ "id": 253,
+ "service_id": "dbtgf28044362",
+ "schedule": "once",
+ "type": "full",
+ "status": "Scheduled",
+ "message": "Backup is scheduled."
+}
+
++you can fetch the Status of the backup using 'https://api.skysql.com/skybackup/v1/backups'. See the 'Backup Status' section for an example. The 'status' field will report Success or failure.
+
To set up an automatic periodic full backup at 3 am UTC, you need to make the following API call:
+curl --location 'https://api.skysql.com/skybackup/v1/backups/schedules' \
+--header 'Content-Type: application/json' \
+--header 'Accept: application/json' \
+--header 'X-API-Key: ${API_KEY}' \
+--data '{
+ "backup_type": "full",
+ "schedule": "0 3 * * *",
+ "service_id": "dbtgf28044362"
+}'
+
For more information about cron schedules take a look at this document.
+Incremental backups can be taken once you have full backup. Read here for more details.
+To set up an one-time incremental backup, you need to make the following API call:
+curl --location 'https://api.skysql.com/skybackup/v1/backups/schedules' \
+--header 'Content-Type: application/json' \
+--header 'Accept: application/json' \
+--header 'X-API-Key: ${API_KEY}' \
+--data '{
+ "backup_type": "incremental",
+ "schedule": "once",
+ "service_id": "dbtgf28044362"
+}'
+
To set up an cron incremental backup, you need to make the following API call:
+curl --location 'https://api.skysql.com/skybackup/v1/backups/schedules' \
+--header 'Content-Type: application/json' \
+--header 'Accept: application/json' \
+--header 'X-API-Key: ${API_KEY}' \
+--data '{
+ "backup_type": "incremental",
+ "schedule": "0 3 * * *",
+ "service_id": "dbtgf28044362"
+}'
+
To set up an one-time binarylog backup:
+curl --location 'https://api.skysql.com/skybackup/v1/backups/schedules' \
+--header 'Content-Type: application/json' \
+--header 'Accept: application/json' \
+--header 'X-API-Key: ${API_KEY}' \
+--data '{
+ "backup_type": "binarylog",
+ "schedule": "once",
+ "service_id": "dbtgf28044362"
+}'
+
To set up an cron incremental backup:
+curl --location 'https://api.skysql.com/skybackup/v1/backups/schedules' \
+--header 'Content-Type: application/json' \
+--header 'Accept: application/json' \
+--header 'X-API-Key: ${API_KEY}' \
+--data '{
+ "backup_type": "binarylog",
+ "schedule": "0 3 * * *",
+ "service_id": "dbtgf28044362"
+}'
+
To set up an one-time dump backup:
+curl --location 'https://api.skysql.com/skybackup/v1/backups/schedules' \
+--header 'Content-Type: application/json' \
+--header 'Accept: application/json' \
+--header 'X-API-Key: ${API_KEY}' \
+--data '{
+ "backup_type": "dump",
+ "schedule": "once",
+ "service_id": "dbtgf28044362"
+}'
+
To set up an cron dump backup:
+curl --location 'https://api.skysql.com/skybackup/v1/backups/schedules' \
+--header 'Content-Type: application/json' \
+--header 'Accept: application/json' \
+--header 'X-API-Key: ${API_KEY}' \
+--data '{
+ "backup_type": "dump",
+ "schedule": "0 3 * * *",
+ "service_id": "dbtgf28044362"
+}'
+
To set up an external storage backup, you need to make the following API call:
+For GCP you need to create an service account key. Please follow the steps from this documentation. Once you have created the service account key you will need to base64 encode it. You can encode it directly from a command line itself. For example the execution of command echo -n 'service-account-key' | base64
will produce something like c2VydmljZS1hY2NvdW50LWtleQ==
curl --location 'https://api.skysql.com/skybackup/v1/backups/schedules' \
+--header 'Content-Type: application/json' \
+--header 'Accept: application/json' \
+--header 'X-API-Key: ${API_KEY}' \
+--data '{
+ "backup_type": "full",
+ "schedule": "0 2 * * *",
+ "service_id": "dbtgf28044362",
+ "external_storage": {
+ "bucket": {
+ "path": "s3://my_backup_bucket",
+ "credentials": "c2VydmljZS1hY2NvdW50LWtleQ=="
+ }
+ }
+}'
+
The service account key will be in the following format:
+{
+ "type": "service_account",
+ "project_id": "XXXXXXX",
+ "private_key_id": "XXXXXXX",
+ "private_key": "-----BEGIN PRIVATE KEY-----XXXXX-----END PRIVATE KEY-----",
+ "client_email": "XXXXXXXXXXXXXXXXXXXXXXXXXXXX.iam.gserviceaccount.com",
+ "client_id": "XXXXXXX",
+ "auth_uri": "<https://accounts.google.com/o/oauth2/auth>",
+ "token_uri": "<https://oauth2.googleapis.com/token>",
+ "auth_provider_x509_cert_url": "<https://www.googleapis.com/oauth2/v1/certs>",
+ "client_x509_cert_url": "<https://www.googleapis.com/robot/v1/metadata/x509/XXXXXXXXXXXXXX.iam.gserviceaccount.com>",
+ "universe_domain": "googleapis.com"
+}
+
For AWS, you must provide your own credentials. These include the AWS access key associated with an IAM account and the bucket region. For more information about AWS credentials, please refer to the documentation. The required credentials are aws_access_key_id , aws_secret_access_key and region. For example your credentials should look like:
+[default]
+aws_access_key_id = AKIAIOSFODNN7EXAMPLE
+aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
+region = us-west-2
+
You should encode your credentials base64 before passing it to the API. You can encode it directly from a command line itself. For example the execution of command echo '[default]\naws_access_key_id = AKIAIOSFODNN7EXAMPLE\naws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\nregion = us-west-2' | base64
will produce the following W2RlZmF1bHRdCmF3c19hY2Nlc3Nfa2V5X2lkID0gQUtJQUlPU0ZPRE5ON0VYQU1QTEUKYXdzX3NlY3JldF9hY2Nlc3Nfa2V5ID0gd0phbHJYVXRuRkVNSS9LN01ERU5HL2JQeFJmaUNZRVhBTVBMRUtFWQpyZWdpb24gPSB1cy13ZXN0LTIK
.
+Using encoded credentials you will be able to pass it to the API server. To initiate a new backup to your external storage you need to execute an API call to the backup service:
```bash
+curl --location '<https://api.skysql.com/skybackup/v1/backups/schedules>' \
+--header 'Content-Type: application/json' \
+--header 'Accept: application/json' \
+--header 'X-API-Key: ${API_KEY}' \
+--data '{
+ "backup_type": "full",
+ "schedule": "0 2 ** *",
+ "service_id": "dbtgf28044362",
+ "external_storage": {
+ "bucket": {
+ "path": "s3://my_backup_bucket",
+ "credentials": "W2RlZmF1bHRdCmF3c19hY2Nlc3Nfa2V5X2lkID0gQUtJQUlPU0ZPRE5ON0VYQU1QTEUKYXdzX3NlY3JldF9hY2Nlc3Nfa2V5ID0gd0phbHJYVXRuRkVNSS9LN01ERU5HL2JQeFJmaUNZRVhBTVBMRUtFWQpyZWdpb24gPSB1cy13ZXN0LTIK"
+ }
+ }
+}'
To get backup schedules inside the Organization :
+curl --location '<https://api.skysql.com/skybackup/v1/backups/schedules>' \
+--header 'Accept: application/json' \
+--header 'X-API-Key: ${API_KEY}'
+
To get backup schedules for specific service :
+curl --location '<https://api.skysql.com/skybackup/v1/backups/schedules?service_id=dbtgf28044362>' \
+--header 'Accept: application/json' \
+--header 'X-API-Key: ${API_KEY}'
+
To get specific backup schedule by id :
+curl --location 'https://api.skysql.com/skybackup/v1/backups/schedules/200' \
+--header 'Accept: application/json' \
+--header 'X-API-Key: ${API_KEY}'
+
In the following example, we update the backup schedule to 9 AM UTC. Remember, you cannot change the schedules for one-time backups. +To update specific backup schedule you need to make the following API call:
+curl --location --request PATCH '<https://api.skysql.com/skybackup/v1/backups/schedules/215>' \
+--header 'Content-Type: application/json' \
+--header 'Accept: application/json' \
+--header 'X-API-Key: ${API_KEY}' \
+--data '{
+ "schedule": "0 9 ** *"
+}'
+
To delete a backup schedule you need to provide the backup schedule id. Example of the api call below:
+curl --location --request DELETE 'https://api.skysql.com/skybackup/v1/backups/schedules/215' \
+--header 'Accept: application/json' \
+--header 'X-API-Key: ${API_KEY}'
+
The following API illustrates how to get the available backups and status of backup jobs .
+Here is an example to fetch all the available Backups in your org:
+curl --location 'https://api.skysql.com/skybackup/v1/backups' \
+--header 'Accept: application/json' \
+--header 'X-API-Key: ${API_KEY}'
+
To list all backups available for your service :
+curl --location 'https://api.skysql.com/skybackup/v1/backups?service_id=dbtgf28216706' \
+--header 'Accept: application/json' \
+--header 'X-API-Key: ${API_KEY}'
+
The typical response of either of two calls should look like:
+{
+ "backups": [
+ {
+ "id": "eda3b72460c8c0d9d61a7f01b6a22e32:dbtgf28216706:tx-filip-mdb-ms-0",
+ "service_id": "dbtgf28216706",
+ "type": "full",
+ "method": "skybucket",
+ "server_pod": "tx-filip-mdb-ms-0",
+ "backup_size": 5327326,
+ "reference_full_backup": "",
+ "point_in_time": "2024-03-26 17:18:21",
+ "start_time": "2024-03-26T17:18:57Z",
+ "end_time": "2024-03-26T17:19:01Z",
+ "status": "Succeeded"
+ }
+ ],
+ "backups_count": 1,
+ "pages_count": 1
+}
+
++The ** Backup id is the most important part of this data as you need to provide it in the restore api call** to schedule restore execution.
+
WARNING
+++restoring from a Backup will likely wipe out all data in your target DB service. If you aren't sure, first take a backup of the Db service where a restore is being performed. The DB being restored will also be stopped during a Restore. You will need restart it.
+
You can restore your database from the backup located in the default SkySQL managed backup storage. In this case, you need to provide the backup ID when making the restore API call. Here is an example:
+curl --location 'https://api.skysql.com/skybackup/v1/restores' \
+--header 'Content-Type: application/json' \
+--header 'Accept: application/json' \
+--header 'X-API-Key: ${API_KEY}' \
+--data '{
+ "key": "eda3b72460c8c0d9d61a7f01b6a22e32:dbtgf28216706:tx-filip-mdb-ms-0",
+ "service_id": "dbtgf28044362"
+}'
+
Inside the service_id parameter of your restore API request, you need to provide the id of the service, where you want to restore your data.
+You can restore your data from external storage. Your external storage bucket data should be created via one of the following tools: mariabackup, mysqldump
. Credentials to external storage access could be fetched from:
For GCP you need to create an service account key. Please follow the steps from this documentation. Once you have created the service account key you will need to base64 encode it. You can encode it directly from a command line itself. For example the execution of command echo -n 'service-account-key' | base64
will produce the following c2VydmljZS1hY2NvdW50LWtleQ==
curl --location 'https://api.skysql.com/skybackup/v1/backups/schedules' \
+--header 'Content-Type: application/json' \
+--header 'Accept: application/json' \
+--header 'X-API-Key: ${API_KEY}' \
+--data '{
+ "backup_type": "full",
+ "schedule": "0 2 * * *",
+ "service_id": "dbtgf28044362",
+ "external_storage": {
+ "bucket": {
+ "path": "s3://my_backup_bucket",
+ "credentials": "c2VydmljZS1hY2NvdW50LWtleQ=="
+ }
+ }
+}'
+
The service account key will be in the following format:
+{
+ "type": "service_account",
+ "project_id": "XXXXXXX",
+ "private_key_id": "XXXXXXX",
+ "private_key": "-----BEGIN PRIVATE KEY-----XXXXX-----END PRIVATE KEY-----",
+ "client_email": "XXXXXXXXXXXXXXXXXXXXXXXXXXXX.iam.gserviceaccount.com",
+ "client_id": "XXXXXXX",
+ "auth_uri": "<https://accounts.google.com/o/oauth2/auth>",
+ "token_uri": "<https://oauth2.googleapis.com/token>",
+ "auth_provider_x509_cert_url": "<https://www.googleapis.com/oauth2/v1/certs>",
+ "client_x509_cert_url": "<https://www.googleapis.com/robot/v1/metadata/x509/XXXXXXXXXXXXXX.iam.gserviceaccount.com>",
+ "universe_domain": "googleapis.com"
+}
+
For AWS, you must provide your own credentials. These include the AWS access key associated with an IAM account and the bucket region. For more information about AWS credentials, please refer to the documentation. The required credentials are aws_access_key_id , aws_secret_access_key and region. For example your credentials should look like:
+[default]
+aws_access_key_id = AKIAIOSFODNN7EXAMPLE
+aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
+region = us-west-2
+
You should encode your credentials base64 before passing it to the API. You can encode it directly from a command line itself. For example the execution of command echo '[default]\naws_access_key_id = AKIAIOSFODNN7EXAMPLE\naws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\nregion = us-west-2' | base64
will produce the following W2RlZmF1bHRdCmF3c19hY2Nlc3Nfa2V5X2lkID0gQUtJQUlPU0ZPRE5ON0VYQU1QTEUKYXdzX3NlY3JldF9hY2Nlc3Nfa2V5ID0gd0phbHJYVXRuRkVNSS9LN01ERU5HL2JQeFJmaUNZRVhBTVBMRUtFWQpyZWdpb24gPSB1cy13ZXN0LTIK
.
The following request demonstrates how to restore your data from an external storage:
+{
+ "service_id": "dbtgf28044362",
+ "key": "/backup.tar.gz",
+ "external_source": {
+ "bucket": "gs://my_backup_bucket",
+ "method": "mariabackup",
+ "credentials" "W2RlZmF1bHRdCmF3c19hY2Nlc3Nfa2V5X2lkID0gQUtJQUlPU0ZPRE5ON0VYQU1QTEUKYXdzX3NlY3JldF9hY2Nlc3Nfa2V5ID0gd0phbHJYVXRuRkVNSS9LN01ERU5HL2JQeFJmaUNZRVhBTVBMRUtFWQpyZWdpb24gPSB1cy13ZXN0LTIK"
+ }
+}
+
In case your backup data is encrypted you need to pass encryption key as well:
+{
+ "service_id": "dbtgf28044362",
+ "key": "/backup.tar.gz",
+ "external_source": {
+ "bucket": "gs://my_backup_bucket",
+ "method": "mariabackup",
+ "credentials": "W2RlZmF1bHRdCmF3c19hY2Nlc3Nfa2V5X2lkID0gQUtJQUlPU0ZPRE5ON0VYQU1QTEUKYXdzX3NlY3JldF9hY2Nlc3Nfa2V5ID0gd0phbHJYVXRuRkVNSS9LN01ERU5HL2JQeFJmaUNZRVhBTVBMRUtFWQpyZWdpb24gPSB1cy13ZXN0LTIK",
+ "encryption_key": "my_encryption_key"
+ }
+}
+
In order to get all Restores scheduled in the past you need to make api call:
+curl --location 'https://api.skysql.com/skybackup/v1/restores' \
+--header 'Accept: application/json' \
+--header 'X-API-Key: ${API_KEY}'
+
curl --location 'https://api.skysql.com/skybackup/v1/restores/12' \
+--header 'Accept: application/json' \
+--header 'X-API-Key: ${API_KEY}'
+
Typical response of those two apis should look like:
+In case restore is in progress:
+[
+ {
+ "id": 12,
+ "service_id": "dbtgf28216706",
+ "bucket": "gs://sky-syst0000-backup-us-84e9d84ecf265a/orgpxw1x",
+ "key": "eda3b72460c8c0d9d61a7f01b6a22e32:dbtgf28216706:tx-filip-mdb-ms-0",
+ "type": "physical",
+ "status": "Running",
+ "message": "server is not-ready"
+ }
+]
+
In case restore completed:
+[
+ {
+ "id": 13,
+ "service_id": "dbtgf28216706",
+ "bucket": "gs://sky-syst0000-backup-us-84e9d84ecf265a/orgpxw1x",
+ "key": "dda9b72460c9c0d9d61a7f01b6a33e39:dbtgf28216706:tx-filip-mdb-ms-0",
+ "type": "physical",
+ "status": "Succeeded",
+ "message": "Restore has succeeded!"
+ }
+]
+
You can delete older completed restore schedules. To clean up your auditing history you need to execute the following api call:
+curl --location --request DELETE 'https://api.skysql.com/skybackup/v1/restores/12' \
+--header 'Accept: application/json' \
+--header 'X-API-Key: ${API_KEY}'
+
Billing is associated with aĀ MariaDB ID.
+For pricing information see "Pricing" .
+From theĀ Portal, you can access a current billing and usage summary:
+Current charges, prior billing date, and next invoice date are shown.
+Usage information can be shown by service or by resource.
+Click the resource name or service name to expand the view.
+ +Billing - Usage
+https://skysql.mariadb.com/billings/usage
+From theĀ Portal, you can access prior invoices:
+Billing - Billing History
+https://skysql.mariadb.com/billings/history
+ + + + + + + + + + + + + +Note
+COMING SOON ā¦ a complete feature checklist of both the tiers ... +A full description of billing and invoicing (FAQ covers a bit)
+Power Tier is a premium service offering who have the most critical requirements for uptime, availability, performance, and support.
+By default, any new signed up users are in the āFoundation Tierā. To upgrade to Power Tier,Ā simply click the āUpgradeā button - SkySQL support will contact you and start the upgrade process. You can also directly reach out to SkySQL Support.
+Features available to SkySQL Power Tier customers include:
+Database server configuration, including system variables, is managed through the Configuration Manager.
+ +Configuration Manager
+https://app.skysql.com/settings/configuration-manager
+To access the Configuration Manager interface:
+Available configuration parameters differ by cloud database topology.
+For cloud databases with the Enterprise Server Single Node topology, the following Configuration Manager parameters are used to configure MariaDB Enterprise Server behavior:
+Parameter
+disconnect_on_expired_password
+explicit_defaults_for_timestamp
+idle_readonly_transaction_timeout
+idle_write_transaction_timeout
+innodb_flush_log_at_trx_commit
+performance_schema_accounts_size
+performance_schema_digests_size
+performance_schema_events_stages_history_long_size
+performance_schema_events_stages_history_size
+performance_schema_events_statements_history_long_size
+performance_schema_events_statements_history_size
+performance_schema_events_waits_history_long_size
+performance_schema_events_waits_history_size
+performance_schema_max_cond_classes
+performance_schema_max_cond_instances
+performance_schema_max_digest_length
+performance_schema_max_file_classes
+performance_schema_max_file_handles
+performance_schema_max_file_instances
+performance_schema_max_mutex_classes
+performance_schema_max_mutex_instances
+performance_schema_max_rwlock_classes
+performance_schema_max_rwlock_instances
+performance_schema_max_socket_classes
+performance_schema_max_socket_instances
+performance_schema_max_stage_classes
+performance_schema_max_table_handles
+performance_schema_max_table_instances
+performance_schema_max_thread_classes
+performance_schema_max_thread_instances
+performance_schema_session_connect_attrs_size
+session_track_system_variables
+simple_password_check_letters_same_case
+simple_password_check_minimal_length
+simple_password_check_other_characters
+system_versioning_alter_history
+For cloud databases with the Enterprise Server With Replica(s) topology, Configuration Manager can be used to configure MariaDB Enterprise Server behavior and MariaDB MaxScale behavior.
+The following Configuration Manager parameters are used to configure MariaDB Enterprise Server behavior:
+Parameter
+disconnect_on_expired_password
+explicit_defaults_for_timestamp
+idle_readonly_transaction_timeout
+idle_write_transaction_timeout
+innodb_flush_log_at_trx_commit
+performance_schema_accounts_size
+performance_schema_digests_size
+performance_schema_events_stages_history_long_size
+performance_schema_events_stages_history_size
+performance_schema_events_statements_history_long_size
+performance_schema_events_statements_history_size
+performance_schema_events_waits_history_long_size
+performance_schema_events_waits_history_size
+performance_schema_max_cond_classes
+performance_schema_max_cond_instances
+performance_schema_max_digest_length
+performance_schema_max_file_classes
+performance_schema_max_file_handles
+performance_schema_max_file_instances
+performance_schema_max_mutex_classes
+performance_schema_max_mutex_instances
+performance_schema_max_rwlock_classes
+performance_schema_max_rwlock_instances
+performance_schema_max_socket_classes
+performance_schema_max_socket_instances
+performance_schema_max_stage_classes
+performance_schema_max_table_handles
+performance_schema_max_table_instances
+performance_schema_max_thread_classes
+performance_schema_max_thread_instances
+performance_schema_session_connect_attrs_size
+rpl_semi_sync_master_wait_no_slave
+rpl_semi_sync_master_wait_point
+rpl_semi_sync_slave_delay_master
+rpl_semi_sync_slave_kill_conn_timeout
+session_track_system_variables
+simple_password_check_letters_same_case
+simple_password_check_minimal_length
+simple_password_check_other_characters
+system_versioning_alter_history
+The following Configuration Manager parameters are used to configure MariaDB MaxScale behavior:
+Parameter
+transaction_replay_retry_on_deadlock
+MariaDB Connector/J enables Java applications to connect to SkySQL and MariaDB database products using a native MariaDB connector.
+Version | +Latest Release | +Latest Release Date | +Maturity | +
---|---|---|---|
MariaDB Connector/J 3.1 | +https://mariadb.com/docs/server/release-notes/mariadb-connector-j-3-1/3-1-4/ | +2023-05-01 | +General Availability | +
MariaDB Connector/J 3.0 | +https://mariadb.com/docs/server/release-notes/mariadb-connector-j-3-0/3-0-10/ | +2023-01-11 | +General Availability | +
MariaDB Connector/J 2.7 | +https://mariadb.com/docs/server/release-notes/mariadb-connector-j-2-7/2-7-9/ | +2023-03-22 | +General Availability | +
MariaDB Connector/J 1.8 | +MariaDB Connector/J 1.8.0 | +2019-02-11 | +GA | +
To download the JAR file manually:
+Maven can install MariaDB Connector/J as a dependency of your application during build. Set theĀ <version>
Ā element to correspond to the version of MariaDB Connector/J that you would like to install.
To use Maven to install MariaDB Connector/J, add the dependency to yourĀ pom.xml
Ā file:
<dependency>
+ <groupId>org.mariadb.jdbc</groupId>
+ <artifactId>mariadb-java-client</artifactId>
+ <version>3.0.10</version>
+</dependency>
+
For additional information on available releases, see the "Release Notes for MariaDB Connector/J".
+Depending on the features you plan to use, you may need to add some additional dependencies toĀ pom.xml
.
If you downloaded the connector JAR, place it on your CLASSPATH
+export CLASSPATH="/path/to/application:/path/to/mariadb-java-client-3.0.10.jar"
+
In MariaDB Connector/J 3.0, TLS is enabled for connections to SkySQL using theĀ sslMode
Ā parameter.
import java.sql.*;
+import java.util.Properties;
+
+public class App {
+ public static void main(String[] argv) {
+ Properties connConfig = new Properties();
+ connConfig.setProperty("user", "db_user");
+ connConfig.setProperty("password", "db_user_password");
+ **connConfig.setProperty("sslMode", "verify-full");**
+
+ try (Connection conn = DriverManager.getConnection("jdbc:mariadb://HOST:PORT", connConfig)) {
+ try (Statement stmt = conn.createStatement()) {
+ try (ResultSet contact_list = stmt.executeQuery("SELECT first_name, last_name, email FROM test.contacts")) {
+ while (contact_list.next()) {
+ System.out.println(String.format("%s %s <%s>",
+ contact_list.getString("first_name"),
+ contact_list.getString("last_name"),
+ contact_list.getString("email")));
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
+
In MariaDB Connector/J 2.7 and before, TLS is enabled for connections to SkySQL using theĀ useSsl
Ā parameter.
import java.sql.*;
+import java.util.Properties;
+
+public class App {
+ public static void main(String[] argv) {
+ Properties connConfig = new Properties();
+ connConfig.setProperty("user", "db_user");
+ connConfig.setProperty("password", "db_user_password");
+ **connConfig.setProperty("useSsl", "true");**
+
+ try (Connection conn = DriverManager.getConnection("jdbc:mariadb://HOST:PORT", connConfig)) {
+ try (Statement stmt = conn.createStatement()) {
+ try (ResultSet contact_list = stmt.executeQuery("SELECT first_name, last_name, email FROM test.contacts")) {
+ while (contact_list.next()) {
+ System.out.println(String.format("%s %s <%s>",
+ contact_list.getString("first_name"),
+ contact_list.getString("last_name"),
+ contact_list.getString("email")));
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
+
Connector | +MariaDB Connector/J | +
---|---|
Supported Versions | +https://mariadb.com/docs/server/release-notes/mariadb-connector-j-3-1/https://mariadb.com/docs/server/release-notes/mariadb-connector-j-3-0/https://mariadb.com/docs/server/release-notes/mariadb-connector-j-2-7/MariaDB Connector/J 1.8 | +
Programming Language | +Java | +
Programming Language Version | +Java 17, Java 11, Java 8 (Connector/J 3.1)Java 17, Java 11, Java 8 (Connector/J 3.0)Java 17, Java 11, Java 8 (Connector/J 2.7)Java 7 (Connector/J 1.8) | +
API | +JDBC 4.2 (Connector/J 3.1)JDBC 4.2 (Connector/J 3.0)JDBC 4.2 (Connector/J 2.7)JDBC 4.1 (Connector/J 1.8) | +
Supports TLS | +Yes | +
License | +GNU Lesser General Public License v2.1 | +
The NoSQL protocol module allows a MariaDB server or cluster to execute transactions for applications using MongoDB client libraries, transparently converting MongoDB API calls into the equivalent SQL. The MariaDB responses are then converted into the format expected by the MongoDBĀ® client library and application.
+For detailed information on supported commands, see "NoSQL Protocol Module" in MariaDB MaxScale documentation.
+ + +Connect to the NoSQL interface using a MongoDB client library or compatible application.Ā Documentation on official MongoDB librariesĀ is available from MongoDB.
+Documentation on installingĀ mongosh
Ā (the MongoDB Shell)Ā is available from MongoDB.
From the Dashboard, the details needed to connect to your SkySQL service can be seen by clicking on the "CONNECT" button for the desired service.
+The "NoSQL port" is the TCP port used to connect to the NoSQL interface.
+TheĀ firewallĀ must be configured to allowlist the client's IP address or netblock before connections can occur.
+See the "Connecting using Mongosh" section of the Connect page for an exampleĀ mongosh
Ā command-line, authentication instructions, and instructions to change the default password.
Node.js developers can connect to MariaDB database products through a native MariaDB Connector. Using MariaDB Connector/Node.js you can connect to MariaDB database products to use and administer databases from within your Node.js application.
+MariaDB Connector/Node.js is usually installed either from the Node.js repository or manually from the source code package.
+To install MariaDB Connector/Node.js from the Node.js repository, use NPM:
+$ npm install mariadb
NPM connects to the Node.js repository and downloads MariaDB Connector/Node.js and all relevant dependencies into theĀ node_modules/
Ā directory.
To download and install the MariaDB Connector/Node.js manually from source code:
+When the source code package finishes downloading, install it with NPM:
+$ npm install mariadb-connector-nodejs-*.tar.gz
NPM untars the download and installs MariaDB Connector/Node.js in theĀ node_modules/
Ā directory.
Node.js developers can use MariaDB Connector/Node.js to establish client connections with MariaDB database products.
+MariaDB Connector/Node.js provides two different connection implementations: one built on theĀ Promise APIĀ and the other built on the Callback API.
+To use the Callback API, use the following module:
+**const** mariadb = require**(**'mariadb/callback'**);**
createConnection(options)Ā ->Ā Connection
Ā is the base function used to create aĀ Connection
Ā object.
TheĀ createConnection(options)
Ā function returns aĀ Connection
Ā object.
Determine theĀ connection informationĀ for your MariaDB SkySQL database service:
+Option | +Description | +
---|---|
host | +The fully Qualified Domain Name in theĀ https://mariadb.com/docs/skysql-previous-release/connect/connection-parameters-portal/ | +
port | +The Read-Write Port or Read-Only Port in theĀ https://mariadb.com/docs/skysql-previous-release/connect/connection-parameters-portal/ | +
user | +The desired username, which might be the default username in the Service Credentials view | +
password | +The user's password, which might be the default password in the Service Credentials view if it was not yet customized | +
database | +Database name to establish a connection to. No default is configured. | +
connectTimeout | +Connection timeout in milliseconds. In Connector/Node.js 2.5.6, the default value changed to 1000. The default value for earlier versions is 10000. | +
rowsAsArray | +A boolean value to indicate whether to return result sets as array instead of the default JSON. Arrays are comparatively faster. | +
The following code example connects using the database and user account created in theĀ example setup:
+const mariadb = require('mariadb/callback');
+
+// Certificate Authority (CA)",
+var serverCert = [fs.readFileSync(process.env.SKYSQL_CA_PEM, "utf8")];
+
+// Declare async function
+function main() {
+ let conn;
+
+ try {
+ conn = mariadb.createConnection({
+ host: "example.skysql.net",
+ port: 5009,
+ ssl: { ca: serverCert },
+ user: "db_user",
+ password: "db_user_password",
+ database: "test",
+ });
+
+ // Use Connection
+ // ...
+ } catch (err) {
+ // Manage Errors
+ console.log("SQL error in establishing a connection: ", err);
+ } finally {
+ // Close Connection
+ if (conn) conn.end(err => {if(err){
+ console.log("SQL error in closing a connection: ", err);}
+ });
+ }
+}
+
+main();
+
try...catch...finally
Ā statement is used for exception handling.connection.end([callback])
Ā function.connection.end([callback])
Ā function to close/end the connection in theĀ finally
Ā block after the queries that are running have completed.end()
Ā function takes a callback function that defines one implicit argument for theĀ Error
Ā object if thrown in closing the connection as argument. If no error is generated in closing a connection theĀ Error
Ā object isĀ null
.Node.js developers can use MariaDB Connector/Node.js to establish client connections with MariaDB database products.
+MariaDB Connector/Node.js provides two different connection implementations: one built on the Promise API and the other built on theĀ Callback API. Promise is the default.
+To use the Promise API, use theĀ mariadb
Ā module:
**const** mariadb = require**(**'mariadb'**);**
createConnection(options)Ā ->Ā Promise
Ā is the base function used to create aĀ Connection
Ā object.
TheĀ createConnection(options)
Ā returns aĀ Promise
Ā that resolves to aĀ Connection
Ā object if no error occurs, and rejects with anĀ Error
Ā object if an error occurs.
Determine theĀ connection informationĀ for your MariaDB SkySQL database service:
+Option | +Description | +
---|---|
host | +The fully Qualified Domain Name in theĀ https://mariadb.com/docs/skysql-previous-release/connect/connection-parameters-portal/ | +
port | +The Read-Write Port or Read-Only Port in theĀ https://mariadb.com/docs/skysql-previous-release/connect/connection-parameters-portal/ | +
user | +The desired username, which might be the default username in the Service Credentials view | +
password | +The user's password, which might be the default password in the Service Credentials view if it was not yet customized | +
ssl.ca | +The contents of theĀ skysql_chain.pemĀ file containing theĀ https://mariadb.com/docs/skysql-previous-release/connect/connection-parameters-portal/#Certificate_Authority_Chain | +
ā¢ https://supplychain.mariadb.com/skysql_chain.pem | ++ |
ā¢ https://supplychain.mariadb.com/aws_skysql_chain.pem | ++ |
database | +Database name to establish a connection to. No default is configured. | +
connectTimeout | +Connection timeout in milliseconds. In Connector/Node.js 2.5.6, the default value changed to 1000. The default value for earlier versions is 10000. | +
rowsAsArray | +A boolean value to indicate whether to return result sets as array instead of the default JSON. Arrays are comparatively faster. | +
Create a file namedĀ .env
Ā to store your database credentials:
MDB_HOST = 192.0.2.50
+MDB_PORT = 3306
+MDB_USER = db_user
+MDB_PASS = db_user_password
+MDB_HOST = example.skysql.net
+MDB_PORT = 5001
+MDB_CA_PEM = /path/to/skysql_chain.pem
+MDB_USER = db_user
+MDB_PASS = db_user_password
+
The following code example connectsĀ using the database and user account created inĀ Setup for Examples:
+// Required Modules
+const fs = require("fs");
+const mariadb = require("mariadb");
+require("dotenv").config()
+
+// Certificate Authority (CA)
+const serverCert = [fs.readFileSync(process.env.MDB_CA_PEM, "utf8")];
+
+// Declare async function
+async function main() {
+ let conn;
+
+ try {
+ conn = await mariadb.createConnection({
+ host: process.env.MDB_HOST,
+ port: process.env.MDB_PORT,
+ user: process.env.MDB_USER,
+ password: process.env.MDB_PASS,
+ ssl: { ca: serverCert },
+ database: "test",
+ });
+
+ // Use Connection
+ // ...
+ } catch (err) {
+ // Manage Errors
+ console.log("SQL error in establishing a connection: ", err);
+ } finally {
+ // Close Connection
+ if (conn) conn.close();
+ }
+}
+
+main();
+
mariadb
Ā module using theĀ require()
Ā function.main()
Ā using theĀ async
Ā keyword.await
Ā expressions using theĀ await
Ā keyword.await
Ā expression is the resolved value of theĀ Promise
.main
Ā is arbitrary and does not have special meaning as in some other programming languages.conn
Ā for the connection to be created using aĀ let
Ā statement with the async functionĀ main
.try...catch...finally
Ā statement is used for exception handling.try
Ā block, create a new connection using theĀ mariadb#createConnection(options)
Ā function in the Promise API.catch
Ā block.close()
Ā function.Connector | +MariaDB Connector/Node.js | +
---|---|
Supported Versions | +https://mariadb.com/docs/server/release-notes/mariadb-connector-nodejs-2-5/https://mariadb.com/docs/server/release-notes/mariadb-connector-nodejs-3-2/ | +
Programming Language | +JavaScript | +
Programming Language Version | +ā¢ Connector/Node.js 2.5: Node.js 16 | +
ā¢ Connector/Node.js 3.2: Node.js 16, 18, 20 | ++ |
API | +Promise APICallback API | +
Supports TLS | +Yes | +
Supports Connection Pools | +Yes | +
License | +GNU Lesser General Public License v2.1 | +
Python developers can use MariaDB Connector/Python to establish client connections with SkySQL database products.
+Connections are managed using the following Python class:
+Class | +Description | +
---|---|
Connection | +Represents a connection to a MariaDB database product. | +
Connections are created, used, and managed using the following Connection
class functions:
Function | +Description | +
---|---|
connect() | +Establishes a connection to a database server and returns a connection object. | +
cursor() | +Returns a new cursor object for the current connection. | +
change_user() | +Changes the user and default database of the current connection. | +
reconnect() | +Tries to make a connection object active again by reconnecting to the server using the same credentials which were specified in connect() method. | +
close() | +Closes the connection. | +
Determine the connection information for your SkySQL database service:
+connect() parameter | +Where to find it | +
---|---|
user | +Default username in the Service Credentials view, or the username you created | +
passwd | +Default password in the Service Credentials view, the password you set on the default user, or the password for the user you created | +
host | +Fully Qualified Domain Name in the Connection Parameters Portal | +
ssl_verify_cert | +Set to True to support SSL | +
port | +Read-Write Port or Read-Only Port in the Connection Parameters Portal | +
The following code example connects to an example server.
+Examples:
+# Module Import
+import mariadb
+import sys
+
+# Instantiate Connection
+try:
+ conn = mariadb.connect(
+ host="192.0.2.1",
+ port=3306,
+ user="db_user",
+ password="USER_PASSWORD")
+except mariadb.Error as e:
+ print(f"Error connecting to the database: {e}")
+ sys.exit(1)
+
+# Use Connection
+# ...
+
+# Close Connection
+conn.close()
+
# Module Import
+import mariadb
+import sys
+
+# Instantiate Connection
+try:
+ conn = mariadb.connect(
+ host="SKYSQL_SERVICE.mdb0000001.db.skysql.com",
+ port=5009,
+ ssl_verify_cert=True,
+ user="DB00000001",
+ password="USER_PASSWORD")
+except mariadb.Error as e:
+ print(f"Error connecting to the database: {e}")
+ sys.exit(1)
+
+# Use Connection
+# ...
+
+# Close Connection
+conn.close()
+
connect()
function returns an instance of the Connection
class, which is assigned to the conn
variable.connect()
function.close()
method.Instantiating the Connection
class creates a single connection to MariaDB database products. Applications that require multiple connections may benefit from pooling connections.
MariaDB Connector/Python closes the connection as part of the class's destructor, which is executed when an instance of the class goes out of scope. This can happen in many cases, such as:
+Connection
class is defined in the local scope of a function, and the function returnsConnection
class is defined as an attribute of a custom class's instance, and the custom class's instance goes out of scope.Connections can also be explicitly closed using the close()
method, which is helpful when the connection is no longer needed, but the variable is still in scope.
Starting with MariaDB Connector/Python 1.1 when MariaDB Connector/Python is built with MariaDB Connector/C 3.3, the connector supports connection failover when auto_reconnect
is
+enabled and the connection string contains a comma-separated list of multiple server addresses.
To enable connection failover:
+mariadb.connect
function with the host
argument specified as a comma-separated list containing multiple server addresses. The connector attempts to connect to the addresses in the order specified in the list.auto_reconnect
to True
. If the connection fails, the connector will attempt to reconnect to the addresses in the order specified in the list.The following code example connects with connection failover enabled:
+# Module Import
+import mariadb
+import sys
+
+# Instantiate Connection
+try:
+ conn = mariadb.connect(
+ host="192.0.2.1,192.0.2.0,198.51.100.0",
+ port=3306,
+ user="db_user",
+ password="USER_PASSWORD")
+ conn.auto_reconnect = True
+except mariadb.Error as e:
+ print(f"Error connecting to the database: {e}")
+ sys.exit(1)
+
+# Use Connection
+# ...
+
+# Close Connection
+conn.close()
+
# Module Import
+import mariadb
+import sys
+
+# Instantiate Connection
+try:
+ conn = mariadb.connect(
+ host="SKYSQL_SERVICE.mdb0000001.db.skysql.com,SKYSQL_SERVICE.mdb0000002.db.skysql.com",
+ port=5009,
+ ssl_verify_cert=True,
+ user="DB00000001",
+ password="USER_PASSWORD")
+ conn.auto_reconnect = True
+except mariadb.Error as e:
+ print(f"Error connecting to the database: {e}")
+ sys.exit(1)
+
+# Use Connection
+# ...
+
+# Close Connection
+conn.close()
+
MariaDB Connector/C++ enables C++ applications to establish client connections to SkySQL and MariaDB databases over TLS.
+MariaDB Connector/C++ has dependencies. You must install MariaDB Connector/C to use it.
+MariaDB Connector/C++ | +MariaDB Connector/C | +
---|---|
1.1 | +3.2.3 or later | +
1.0 | +3.1.1 or later | +
For additional information, see "MariaDB Connector/C++ Release Notes".
+To install MariaDB Connector/C++ on Linux:
+Extract the tarball:
+$ tar -xvzf mariadb-connector-cpp-*.tar.gz
Change into the relevant directory:
+$ cd mariadb-connector-cpp-*/
Install the directories for the header files:
+$ sudo install -d /usr/include/mariadb/conncpp
+$ sudo install -d /usr/include/mariadb/conncpp/compat
Install the header files:
+$ sudo install include/mariadb/* /usr/include/mariadb/
+$ sudo install include/mariadb/conncpp/* /usr/include/mariadb/conncpp
+$ sudo install include/mariadb/conncpp/compat/* /usr/include/mariadb/conncpp/compat
Install the directories for the shared libraries:
+On CentOS, RHEL, Rocky Linux:
+$ sudo install -d /usr/lib64/mariadb
+$ sudo install -d /usr/lib64/mariadb/plugin
On Debian, Ubuntu:
+$ sudo install -d /usr/lib/mariadb
+$ sudo install -d /usr/lib/mariadb/plugin
Install the shared libraries:
+On CentOS, RHEL, Rocky Linux:
+$ sudo install lib64/mariadb/libmariadbcpp.so /usr/lib64
+$ sudo install lib64/mariadb/plugin/* /usr/lib64/mariadb/plugin
On Debian, Ubuntu:
+$ sudo install lib/mariadb/libmariadbcpp.so /usr/lib
+$ sudo install lib/mariadb/plugin/* /usr/lib/mariadb/plugin
To install MariaDB Connector/C++ on Windows:
+mariadbcpp
Ā LIB
Ā file (exampleĀ "C:\ProgramĀ Files\MariaDB\MariaDBĀ C++Ā ConnectorĀ 64-bit"
) toĀ PATH
Ā environment variable.Version | +Latest Release | +Latest Release Date | +Maturity | +
---|---|---|---|
MariaDB Connector/C++ 1.1 | +https://mariadb.com/docs/server/release-notes/mariadb-connector-cpp-1-1/1-1-2/ | +2022-11-30 | +Release Candidate | +
MariaDB Connector/C++ 1.0 | +https://mariadb.com/docs/server/release-notes/mariadb-connector-cpp-1-0/1-0-2/ | +2022-10-11 | +General Availability | +
The connection is configured via the information that is initially acquired from the SkySQL Portal pages:
+What to set | +Where to find it | +
---|---|
Hostname in the URL | +The fully Qualified Domain Name in theĀ https://mariadb.com/docs/skysql-previous-release/connect/connection-parameters-portal/ | +
Port number in the URL | +The Read-Write Port or Read-Only Port in theĀ https://mariadb.com/docs/skysql-previous-release/connect/connection-parameters-portal/ | +
userĀ parameter | +The desired username, which might be the default username in the Service Credentials view | +
passwordĀ parameter | +The user's password, which might be the default password in the Service Credentials view if it was not yet customized | +
tlsCertĀ parameter | +The path to theĀ skysql_chain.pemĀ file containing theĀ https://mariadb.com/docs/skysql-previous-release/connect/connection-parameters-portal/#Certificate_Authority_Chain | +
ā¢ https://supplychain.mariadb.com/skysql_chain.pem | ++ |
ā¢ https://supplychain.mariadb.com/aws_skysql_chain.pem | ++ |
While MariaDB Connector/C++ supports several connection styles, we are going to detail just the JDBC syntax since all connections to SkySQL use a single idiom of hostname, port, user, password, and SSL parameters.
+The base URL is specified as follows:
+jdbc:mariadb://example.skysql.net:5001/dbname
If the trailing database name is left off of the URL, the connection will start without selecting a database.
+MariaDB Connector/C++ supports several optional connection parameters. These parameters can be specified using aĀ Properties
Ā object, as we do in our examples, or appended to the URL in standardĀ name=value
Ā query-string encoding.
In the following list, we've left out any parameters that aren't pertinent to accessing SkySQL:
+Parameter Name | +Description | +Type | +Default | +Aliases | +
---|---|---|---|---|
autoReconnect | +Defines whether the connector automatically reconnects after a connection failure. | +bool | +false | +ā¢ OPT_RECONNECT | +
connectTimeout | +Defines the connect timeout value in milliseconds. When set toĀ 0, there is no connect timeout. | +int | +30000 | ++ |
enabledTlsCipherSuites | +A list of permitted ciphers or cipher suites to use for TLS. | +string | ++ | ā¢ enabledSslCipherSuites | +
ā¢ enabledSSLCipherSuites | ++ | + | + | + |
jdbcCompliantTruncation | +This mode is enabled by default. This mode configures the connector to addĀ STRICT_TRANS_TABLESĀ toĀ https://mariadb.com/docs/server/ref/mdb/system-variables/sql_mode/https://mariadb.com/docs/server/ref/mdb/system-variables/sql_mode/, which causes ES to handle truncation issues as errors instead of warnings. | +bool | +true | ++ |
password | +Defines the password of the user account to connect with. | ++ | + | + |
socketTimeout | +Defines the network socket timeout (SO_TIMEOUT) in milliseconds. When set toĀ 0, there is no socket timeout. This connection parameter is not intended to set a maximum time for statements. To set a maximum time for statements, please see theĀ https://mariadb.com/docs/server/ref/mdb/system-variables/max_statement_time/https://mariadb.com/docs/server/ref/mdb/system-variables/max_statement_time/https://mariadb.com/docs/server/ref/mdb/system-variables/max_statement_time/Ā system variable. | +int | +0 | +ā¢ OPT_READ_TIMEOUT | +
tcpRcvBuf | +The buffer size for TCP/IP and socket communication.Ā tcpSndBufĀ changes the same buffer value, and the biggest value of the two is selected. | +int | +0x4000 | +ā¢ tcpSndBuf | +
tcpSndBuf | +The buffer size for TCP/IP and socket communication.Ā tcpRcvBufĀ changes the same buffer value, and the biggest value of the two is selected. | +int | +0x4000 | +ā¢ tcpRcvBuf | +
tlsCert | +Path to the X509 certificate file. | +string | ++ | ā¢ sslCert | +
tlsCRL | +Path to a PEM file that should contain one or more revoked X509 certificates. | +string | ++ | ā¢ tlsCrl | +
ā¢ sslCRL | ++ | + | + | + |
useCompression | +Compresses network traffic between the client and server. | +bool | +false | +ā¢ CLIENT_COMPRESS | +
user | +Defines the user name of the user account to connect with. | ++ | + | ā¢ userName | +
useServerPrepStmts | +Defines whether the connector uses server-side prepared statements using theĀ https://mariadb.com/docs/skysql-previous-release/ref/mdb/sql-statements/PREPARE/,Ā https://mariadb.com/docs/skysql-previous-release/ref/mdb/sql-statements/EXECUTE/, andĀ https://mariadb.com/docs/skysql-previous-release/ref/mdb/sql-statements/DROP_PREPARE/Ā statements. By default, the connector uses client-side prepared statements. | +bool | +false | ++ |
useTls | +Whether to force TLS. This enables TLS with the default system settings. | +bool | ++ | ā¢ useSsl | +
ā¢ useSSL | ++ | + | + | + |
Two categories of methods are available to to establish a connection.
+MariaDB Connector/C++ can connect using the non-staticĀ connect()
Ā methods in theĀ sql::Driver
Ā class.
The non-staticĀ connect()
Ā methods in theĀ sql::Driver
Ā class have the following prototypes:
Connection*Ā connect(constĀ SQLString&Ā url,Ā Properties&Ā props);
Connection*Ā connect(constĀ SQLString&Ā host,Ā constĀ SQLString&Ā user,Ā constĀ SQLString&Ā pwd);
Connection*Ā connect(constĀ Properties&Ā props);
The non-staticĀ connect()
Ā methods in theĀ sql::Driver
Ā class:
sql::Driver
Ā class to establish a connection.nullptr
Ā as theĀ Connection*
Ā value when an error occurs, so applications should check the return value before use.For example:
+// Instantiate Driver
+sql::Driver* driver = sql::mariadb::get_driver_instance();
+
+// Configure Connection, including an optional initial database name "places":
+sql::SQLString url("jdbc:mariadb://example.skysql.net:5009/places");
+
+// Use a properties map for the other connection options
+sql::Properties properties({
+ {"user", "db_user"},
+ {"password", "db_user_password"},
+ {"autocommit", false},
+ {"useTls", true},
+ {"tlsCert", "classpath:static/skysql_chain.pem"},
+ });
+
+// Establish Connection
+// Use a smart pointer for extra safety
+std::unique_ptr<sql::Connection> conn(driver->connect(url, properties));
+
+if (!conn) {
+ cerr << "Invalid database connection" << endl;
+ exit (EXIT_FAILURE);
+}
+
MariaDB Connector/C++ can connect using the staticĀ getConnection()
Ā methods in theĀ sql::DriverManager
Ā class.
The staticĀ getConnection()
Ā methods in theĀ sql::DriverManager
Ā class have the following prototypes:
staticĀ Connection*Ā getConnection(constĀ SQLString&Ā url);
staticĀ Connection*Ā getConnection(constĀ SQLString&Ā url,Ā Properties&Ā props);
staticĀ Connection*Ā getConnection(constĀ SQLString&Ā url,Ā constĀ SQLString&Ā user,Ā constĀ SQLString&Ā pwd);
The staticĀ getConnection()
Ā methods in theĀ sql::DriverManager
Ā class:
sql::DriverManager
Ā class to establish a connection, because they are static.tryĀ {Ā ..Ā }Ā catchĀ (Ā ..Ā )Ā {Ā ..Ā }
Ā to catch the exception.For example:
+try {
+ // Configure Connection, including an optional initial database name "places":
+ sql::SQLString url("jdbc:mariadb://example.skysql.net:5009/places");
+
+ // Use a properties map for the other connection options
+ sql::Properties properties({
+ {"user", "db_user"},
+ {"password", "db_user_password"},
+ {"autocommit", false},
+ {"useTls", true},
+ {"tlsCert", "classpath:static/skysql_chain.pem"},
+ });
+
+ // Establish Connection
+ // Use a smart pointer for extra safety
+ std::unique_ptr<sql::Connection> conn(DriverManager::getConnection(url, properties));
+ } catch (...) {
+ cerr << "Invalid database connection" << endl;
+ exit (EXIT_FAILURE);
+}
+
The following code demonstrates how to connect using theĀ example database and user account:
+// Includes
+#include <iostream>
+#include <mariadb/conncpp.hpp>
+
+// Main Process
+int main(int argc, char **argv)
+{
+ try {
+ // Instantiate Driver
+ sql::Driver* driver = sql::mariadb::get_driver_instance();
+
+ // Configure Connection, including initial database name "test":
+ sql::SQLString url("jdbc:mariadb://example.skysql.net:5009/test");
+
+ // Use a properties map for the other connection options
+ sql::Properties properties({
+ {"user", "db_user"},
+ {"password", "db_user_password"},
+ {"autocommit", false},
+ {"useTls", true},
+ {"tlsCert", "classpath:static/skysql_chain.pem"},
+ });
+
+ // Establish Connection
+ // Use a smart pointer for extra safety
+ std::unique_ptr<sql::Connection> conn(driver->connect(url, properties));
+
+ // Use Connection
+ // ...
+
+ // Close Connection
+ conn->close();
+ }
+
+ // Catch Exceptions
+ catch (sql::SQLException& e) {
+ std::cerr << "Error Connecting to the database: "
+ << e.what() << std::endl;
+
+ // Exit (Failed)
+ return 1;
+ }
+
+ // Exit (Success)
+ return 0;
+}
+
MariaDB Connector/C enables C and C++ applications to establish client connections to SkySQL over TLS. MariaDB Connector/C is a native connector that is written in C.
+MariaDB Connector/C is compatible with:
+MariaDB Connector/C enables C and C++ applications to establish client connections to SkySQL and MariaDB database products over TLS.
+Additional information on MariaDB Connector/C is available in theĀ MariaDB Knowledge Base.
+The connection is configured via the information that is initially acquired from the SkySQL Portal pages:
+Function | +Option/Argument | +Where to find it | +
---|---|---|
mysql_optionsv() | +MYSQL_OPT_SSL_CAĀ option | +The path to theĀ skysql_chain.pemĀ file containing theĀ https://mariadb.com/docs/skysql-previous-release/connect/connection-parameters-portal/#Certificate_Authority_Chain | +
ā¢ https://supplychain.mariadb.com/skysql_chain.pem | ++ | + |
ā¢ https://supplychain.mariadb.com/aws_skysql_chain.pem | ++ | + |
mysql_real_connect() | +hostĀ argument | +The fully Qualified Domain Name in theĀ https://mariadb.com/docs/skysql-previous-release/connect/connection-parameters-portal/ | +
mysql_real_connect() | +userĀ argument | +The desired username, which might be the default username in the Service Credentials view | +
mysql_real_connect() | +passwdĀ argument | +The user's password, which might be the default password in the Service Credentials view if it was not yet customized | +
mysql_real_connect() | +portĀ argument | +The Read-Write Port or Read-Only Port in theĀ https://mariadb.com/docs/skysql-previous-release/connect/connection-parameters-portal/ | +
The following code demonstrates how to use MariaDB Connector/C to connect to MariaDB database products. This example uses theĀ example database and user account:
+#include <stdio.h>
+#include <stdlib.h>
+#include <mysql.h>
+
+int main (int argc, char* argv[])
+{
+
+ // Initialize Connection
+ MYSQL *conn;
+ if (!(conn = mysql_init(0)))
+ {
+ fprintf(stderr, "unable to initialize connection struct\n");
+ exit(1);
+ }
+
+ // Connect to the database
+ if (!mysql_real_connect(
+ conn, // Connection
+ "example.skysql.com", // Host
+ "db_user", // User account
+ "db_user_password", // User password
+ "test", // Default database
+ 3006, // Port number
+ NULL, // Path to socket file
+ 0 // Additional options
+ ))
+ {
+ // Report the failed-connection error & close the handle
+ fprintf(stderr, "Error connecting to Server: %s\n", mysql_error(conn));
+ mysql_close(conn);
+ exit(1);
+ }
+
+ // Use the Connection
+ // ...
+
+ // Close the Connection
+ mysql_close(conn);
+
+ return 0;
+}
+
Java developers can use MariaDB Connector/R2DBC to connect to MariaDB database products using the Reactive Relational Database Connectivity (R2DBC) API. R2DBC operations are non-blocking, which makes the R2DBC API more scalable than Java's standard JDBC API. MariaDB Connector/R2DBC is available both with a native R2DBC implementation and the Spring Data R2DBC framework.
+Connector | +MariaDB Connector/R2DBC | +MariaDB Connector/R2DBC | +
---|---|---|
Supported Versions | +1.0 | +1.1 | +
Programming Language | +Java | +Java | +
Programming Language Version | +Java 8+ | +Java 8+ | +
API | +https://r2dbc.io/spec/0.8.5.RELEASE/spec/html/ | +https://r2dbc.io/spec/1.0.0.RELEASE/spec/html | +
Supports TLS | +Yes | +Yes | +
Supports Connection Pools | +Yes | +Yes | +
License | +Apache 2.0 | +Apache 2.0 | +
For details on how to use MariaDB Connector/R2DBC, choose a supported framework:
+https://mariadb.com/docs/skysql-previous-release/connect/programming-languages/java-r2dbc/native/ | +The native implementation of R2DBC can be used to connect using MariaDB Connector/R2DBC from within your Java application. | +
---|---|
https://mariadb.com/docs/skysql-previous-release/connect/programming-languages/java-r2dbc/spring/ | +Spring Data implementation of R2DBC allows you to connect using MariaDB Connector/R2DBC using the Spring Framework. | +
Application developers can use MariaDB Connector/ODBC to establish a data source for client connections with MariaDB database products.
+The method for configuring the data source varies between operating systems.
+Configure unixODBC
to recognize the driver by creating a file called MariaDB_odbc_driver_template.ini
with the relevant driver definition.
For example, on CentOS / RHEL / Rocky Linux:
+[MariaDB ODBC 3.1 Driver]
+Description = MariaDB Connector/ODBC v.3.1
+Driver = /usr/lib64/libmaodbc.so
+
On Debian / Ubuntu:
+[MariaDB ODBC 3.1 Driver]
+Description = MariaDB Connector/ODBC v.3.1
+Driver = /usr/lib/libmaodbc.so
+
Install the driver using the odbcinst
command.
For example:
+$ sudo odbcinst -i -d -f MariaDB_odbc_driver_template.ini
+odbcinst: Driver installed. Usage count increased to 1.
+Target directory is /etc
+
Determine the connection parameters for your database.
+Configure unixODBC
to connect to the data source by creating a file called MariaDB_odbc_data_source_template.ini
with the relevant data source parameters. Be sure to specify SSLVERIFY = 1
for your SkySQL database.
For example:
+# Data Source for unixODBC
+[My-Test-Server]
+Description = Describe your database setup here
+Driver = MariaDB ODBC 3.1 Driver
+Trace = Yes
+TraceFile = /tmp/trace.log
+SERVER = localhost
+SOCKET = /var/run/mysqld/mysqld.sock
+USER = db_user
+PASSWORD = db_user_password
+DATABASE = test
+
# Data Source for unixODBC
+[My-Test-Server]
+Description = Describe your database setup here
+Driver = MariaDB ODBC 3.1 Driver
+Trace = Yes
+TraceFile = /tmp/trace.log
+SERVER = example.skysql.com
+PORT = 3306
+SSLVERIFY = 1
+USER = db_user
+PASSWORD = db_user_password
+DATABASE = test
+
SSLCA = /path/to/ca-cert.pem
+SSLKEY = /path/to/client-key.pem
+SSL_CERT = /path/to/client-cert.pem
+
Install the unixODBC
data source template file:
$ sudo odbcinst -i -s -h -f MariaDB_odbc_data_source_template.ini
+
Test the data source My-Test-Server
configured in the MariaDB_odbc_data_source_template.ini
+file using the isql
command. If you see the output below, you have successfully connected to your Sky database.
$ isql -v My-Test-Server
++-------------------------+
+| Connected! |
+| sql-statement |
+| help[tablename] |
+| quit |
++-------------------------+
+SQL>
+
To select your new data source in your application, select the data source with the name that you configured, which is My-Test-Server
in the above example.
Confirm that MariaDB Connector/ODBC has been registered withiODBC
by confirming that the following options are set in the iODBC
configuration file at /Library/ODBC/odbcinst.ini
:
[ODBC]
+Trace = no
+TraceFile = /tmp/iodbc_trace.log
+
+[ODBC Drivers]
+MariaDB ODBC 3.1 Unicode Driver = Installed
+
+[MariaDB ODBC 3.1 Unicode Driver]
+Driver = /Library/MariaDB/MariaDB-Connector-ODBC/libmaodbc.dylib
+Description = MariaDB Connector/ODBC(Unicode) 3.1 64bit
+Threading = 0
+
Determine the connection parameters for your database.
+Add a data source for your database to iODBC
by adding the following options to the iODBC
configuration file at /Library/ODBC/odbc.ini
:
[ODBC Data Sources]
+My-Test-Server = MariaDB ODBC 3.1 Unicode Driver
+
+[My-Test-Server]
+Driver = /Library/MariaDB/MariaDB-Connector-ODBC/libmaodbc.dylib
+SERVER = 192.0.2.1
+DATABASE = test
+USER = db_user
+PASSWORD = db_user_password
+
SERVER
, SOCKET
, DATABASE
, PORT
, USER
, and PASSWORD
parameters with the relevant value for your environment.iodbctest
command:$ iodbctest "DSN=My-Test-Server"
+
To select your new data source in your application, select the data source with the name that you configured, which is My-Test-Server
in the above example.
MariaDB Connector/ODBC requires at least Windows 8.
+Windows 10 was used to prepare these instructions. When using other versions of Windows, these instructions may require adjustment.
+MariaDB Connector/ODBC supports failover in case one or more hosts are not available.
+The failover feature requires using MariaDB Connector/ODBC 3.1.16 or greater with MariaDB Connector/C 3.3 or greater.
+MariaDB Connector/ODBC 3.1.16 and greater is statically linked for Windows and macOS with MariaDB Connector/C 3.3.1. MariaDB Connector/ODBC 3.1.16 and greater is dynamically linked for Linux with MariaDB Connector/C.
+The failover feature is enabled by providing a comma separated list of hosts as a server name.
+The failover host string is the SERVER
string. If the SERVER
string does not include a port, the default port will be used.
The following syntax is required:
+"[]"
":"
hostname:port
pairs must be be separated by a comma ","
hostname:port
is specified, the host string must end with a commaAn example of a failover host string:
+[::1]:3306,192.168.0.1:3307,test.example.com
Connection Parameter | +Description | +Default Value | +
---|---|---|
DRIVER | +ā¢ On Linux, the name of the driver, which is configured in the | ++ |
unixODBC driver template file. | ++ | + |
ā¢ On macOS, the path to the driver's shared library, which is | ++ | + |
installed at /Library/MariaDB/MariaDB-Connector-ODBC/libmaodbc.dylib | ++ | + |
by default. | ++ | + |
SERVER | +Host name, IPv4 address, or IPv6 address of the database | ++ |
server. | +localhost | ++ |
SOCKET | +ā¢ The path to the socket file. On Linux, MariaDB Enterprise Server | ++ |
uses different default socket files on different Linux | ++ | + |
distributions. | ++ | + |
ā¢ On Debian / Ubuntu, the default socket file is /var/run/mysqld/mysqld.sock | ++ | + |
or /run/mysqld/mysqld.sock. | ++ | + |
ā¢ On CentOS / RHEL / Rocky Linux, the default socket file is /var/lib/mysql/mysql.sock. | +/tmp/mysql.sock | ++ |
DATABASE | +Database name to select upon successful connection. The database | ++ |
must already exist, and the user account must have privileges to select | ++ | + |
it. | ++ | + |
PORT | +TCP port of the database server. | +3306 | +
USER | +The username to use for authentication. | ++ |
PASSWORD | +User password. | ++ |
FORWARDONLY | +When enabled, cursors are created as SQL_CURSOR_FORWARD_ONLY, | ++ |
so they can only move forward. Starting in Connector/ODBC 3.2, cursors | ++ | + |
are SQL_CURSOR_FORWARD_ONLY | ++ | + |
by default. In previous releases, cursors are created as SQL_CURSOR_STATIC by | ++ | + |
default. | ++ | + |
NO_CACHE | +When enabled, result set streaming is enabled, which enables the | ++ |
application to fetch result sets from the server row-by-row instead of | ++ | + |
caching the entire result set on the client side. Since the application | ++ | + |
is not caching the entire result set, the application is less likely to | ++ | + |
run out of memory when working with large result sets. | ++ | + |
STREAMRS | +Alias for the NO_CACHE connection | ++ |
parameter. | ++ | + |
OPTIONS | +See about:blank#OPTIONS_Bitmaskabout:blank#OPTIONS_Bitmask. | ++ |
PREPONCLIENT | +When enabled, the SQLPrepare ODBC API | ++ |
function uses the text protocol and client-side prepared statements | ++ | + |
(CSPS). | ++ | + |
ATTR | +Sets connection attributes that can be queried via the https://www.notion.so../../../../ref/mdb/performance-schema/session_account_connect_attrs/https://www.notion.so../../../../../server/ref/mdb/performance-schema/session_account_connect_attrs/ | ++ |
and https://www.notion.so../../../../ref/mdb/performance-schema/session_connect_attrs/https://www.notion.so../../../../../server/ref/mdb/performance-schema/session_connect_attrs/ | ++ | + |
tables when https://www.notion.so../../../../ref/mdb/system-variables/performance_schema/https://www.notion.so../../../../../server/ref/mdb/system-variables/performance_schema/ | ++ | + |
is enabled. Specify attributes in the format ATTR={ |
++ | + |
What | +Where to find it | +
---|---|
DRIVER | +ā¢ On Linux, the name of the driver, which is configured in the | +
unixODBC driver template file. | ++ |
ā¢ On macOS, the path to the driver's shared library, which is | ++ |
installed at /Library/MariaDB/MariaDB-Connector-ODBC/libmaodbc.dylib | ++ |
by default. | ++ |
SERVER | +Fully Qualified Domain Name in the https://www.notion.so../../../connection-parameters-portal/ | +
PORT | +Read-Write Port or Read-Only Port in the https://www.notion.so../../../connection-parameters-portal/ | +
USER | +Default username in the Service Credentials view, or the username | +
you created | ++ |
PASSWORD | +Default password in the Service Credentials view, the password | +
you set on the default user, or the password for the user you | ++ |
created | ++ |
SSLVERIFY | +Set to 1 to connect with SSL | +
FORCETLS | +Set to 1 to enable TLS | +
FORWARDONLY | +When enabled, cursors are created as SQL_CURSOR_FORWARD_ONLY, | +
so they can only move forward. Starting in Connector/ODBC 3.2, cursors | ++ |
are SQL_CURSOR_FORWARD_ONLY | ++ |
by default. In previous releases, cursors are created as SQL_CURSOR_STATIC by | ++ |
default. | ++ |
NO_CACHE | +When enabled, result set streaming is enabled, which enables the | +
application to fetch result sets from the server row-by-row instead of | ++ |
caching the entire result set on the client side. Since the application | ++ |
is not caching the entire result set, the application is less likely to | ++ |
run out of memory when working with large result sets. | ++ |
STREAMRS | +Alias for the NO_CACHE connection | +
parameter. | ++ |
OPTIONS | +See about:blank#OPTIONS_Bitmaskabout:blank#OPTIONS_Bitmask. | +
PREPONCLIENT | +When enabled, the SQLPrepare ODBC API | +
function uses the text protocol and client-side prepared statements | ++ |
(CSPS). | ++ |
ATTR | +Sets connection attributes that can be queried via the https://www.notion.so../../../../ref/mdb/performance-schema/session_account_connect_attrs/ | +
and https://www.notion.so../../../../ref/mdb/performance-schema/session_connect_attrs/ | ++ |
tables when https://www.notion.so../../../../ref/mdb/system-variables/performance_schema/ | ++ |
is enabled. Specify attributes in the format ATTR={ |
++ |
OPTIONS
BitmaskThe OPTIONS
bitmask
+contains the following bits:
Bit Number | +Bit Value | +Description | +
---|---|---|
0 | +1 | +Unused | +
1 | +2 | +Tells connector to return the number of matched rows instead of | +
number of changed rows | ++ | + |
4 | +16 | +Same as NO_PROMPT connection | +
parameter | ++ | + |
5 | +32 | +Forces all cursors to be dynamic | +
6 | +64 | +Forbids the DATABASE_NAME.TABLE_NAME.COLUMN_NAME | +
syntax | ++ | + |
11 | +2048 | +Enables compression in the protocol | +
13 | +8192 | +Same as the NAMEDPIPE connection | +
parameter | ++ | + |
16 | +65536 | +Same as the USE_MYCNF connection | +
parameter | ++ | + |
20 | +1048576 | +Same as the NO_CACHE connection | +
parameter | ++ | + |
21 | +2097152 | +Same as the FORWARDONLY | +
connection parameter | ++ | + |
22 | +4194304 | +Same as the AUTO_RECONNECT | +
connection parameter | ++ | + |
26 | +67108864 | +Enables multi-statement queries | +
KiSM%r8p_ z`K~;ie%bJ$z2^J9&Q8NM)XuJfSMu8Ga(R!W)p*p7DZ!7;JD(p?#}G5C#yuk6*hrI? zZR>SvBDm-weWCihUsKoh$Nujw61*y(#;r7g?$eiHEwvCQ_`OqG5((eSv;+^YOnI1G z7ABi2|5*P!s5zb>jhw}4d|9QBs***8nuYA%@yj4eD-YM8>D=37IWCP)^sZ=K_#P#4 z$LSuyeX*OlR!)?k#qPVm=L(Q`d)@3tBizPjLE^poUAyB6t~xV&@P<4}1nhnpmB=F(eXLj$%b2BD7QYbCw rUCujvgCYSy_i`yfMwV! Hf6Om=oqPH!P2`jyNpP1fX3W4w~dT)z`~ zat#d)uorourdB3_?iCAOSNiNbTZBXjCL_f~MMwB(x1`9w$6FJ8bf10oA@xGU0MX>A z4E$M=AZ22m@-690&VD4?Z&^1TUS8_-6D%d}{?6cWLF)RIMri>(l5fmcv+gEa`47D$ z{6R?cl6aU<>HA$rD(!bslLFS4xF&CYBe8#H??@|g+2`f;+Kc9sgmHe%SBO8~CCMVO zkvWWb^qTB3v+fU462B*D)(^>*-oKByWIzUaN0Rm=?~>TX7cx>$=hBpWp?SofS9YGV z^cv2ShP+ecrAGUay(Ephz;6Z at+8Y3jtK3 *nXQ0hrKnSHD3Z#?uku&e35@3LQaFaXA zXzDZCcHTDF)^WXBeRJH;ULGg6m)X{fd;B^?td(l|y_tCi@25CB6~>$^T4DKZMh#;v z*Ir4!EYqVyUtjXuX^}IJDl05CEF&(34(r%axDkklHBD(d<%rN4F^BngG|x=!PN_|D z|MGP5|EBJ7yOw5xZY?ytfpmj@Lw4Wxn8=&Q_llHE1lv4i(v`QD7|kA-iBH{1k9Q2_ zRfuC|zfSgvyP5YDpA%tOoSt&+6YnS9Y%DC9EYlAuIawm~d9*lPlx7oD>N~9>@BMt= ze6J<)eikH)M3ZCT?gB%+iV$;6l=+YN-;m$zn--h=n{4_)MOB=JF>EzzNNuDHQg;_| zM@G#w>`|pQw>(^7HDrvdO5@GD+P4zQDJ=Cmb=oIM$36#6L_zPOpQJrWXw(U?4Ok*+ z3KEeel;x34c?JKa(b5q_NJS+Z+nC|_DDh$2L*0k|+MGiX?K!Mkq @*#$Oj~%8RpZg2msQXhlU#qHc zQ#KmDn4OSOt%cCo$)_{udd8*4Ww??yN{#4yGx(-^>)Y1mTyn~u0)vjQ28D)cwy!oy z%g5-cR+IeGtTOfKudR8kssqOS`Yx5TL|r$yf?^6|q`{SF+2UB&2VzkvN<2B018o&U z2p`0QQTd9R3O3hk&_<}x;^2bB(1S%jS4vm+CFDZbg3SWgpkc9Y=AJ@oT2HTfKdum$ ze%klFm%0CCxlCq5X?oCIEN@$B>-wh~BR{&Vt2E;K7|e?vH;J_D`#Du!wR>e1`C8M~ zxr0gwAxs^|$h#6B9=|4HDpGHE;=><#dw{c}sI>@}WXbrluCKQ57!i;n8`7c{Odh-z z;}(-2)5ghU_{iWuA5vk9^aMj*bs@MBb>>fz8%TYtf!ABD=)o8Vuio9a3@!HQ yMx_yvcNw#|H0PURRE?A|E_rzRrl+lo6^s%qfkJ*Y9Ck2akumMJgmc1yRf zdkuPdzZNY+ml}XHQY2FjQjAT4Or}g8nDo>_YbjCS+BWZHZ=HjR!&lyTANRuvD{yJm zGW%{^sy~jd-VGKB%Y%J7-6Du0aFX77;*pMPG$u{u>^Hq{G JVYm$=9zHI 9(nf^Qc(c4GVkD~HF=R +4mZ`%?g|TSyCN>g#t@jZqIh(sYy8AbBO6C6pej#e%K~H zx6i)KzFL4B8Z8tqS~YDla(T^FA><3eij707mM&wCib}?$$0EK?VM1f*NrmfhR8{$+ zx-9NKtKTUkr3Qchoc*-5>fkovJukl<{*I{zIczslIpZbCb1L`NLPnzjQ#@8I?ECdF ze?Rvp BV&Mg+9id?uRUYFQ z!Rp?5K31XbfD7|6RgP3zjq&_~UeU$XTb#BL))JzK$0^W^{UX|q^BralQ^fM#VFF)n zf1ze*VeAq+{H51i7B(F+{bI&;hG+)I{+`+=`fl{f3-T8)h8Bmg;7K~gt{ Ow;aLyY;EL)1wZbMNPxoZQ*lLJgecV!L^}2UCWmYU)!oQ*i`>MRvEqDz?kuAp1qp zId^#RNLAGd?UpIKL4~1G4@WZ2_pQg>y~f`yNx{>_8R$OcPqCLrV-TRaJJ16)FGnv7 z^(hAi?rDk|Ygqo~(KTbx0nJ^Sv*)!Jn5d{9>9xV=pB9dn>=^GFlU3fa7lewt3GZ>v zSM@HTy%vyjD~0aE?)DSLu9b5p`zYc)^R+$DB K~ zu>3171Xj3Iz9x=a8^Ik&Y#&TtSp8mz 2#>(+*uYe7#h>N@5a~Q*)BdBflqi)D#FNAw&ePpNT)OzJV|G zkW*Ku7uX`>Rh^XD2$@Y0@*=SPY^Fq0W^h3y;9G+y!Rya+j})n9$zRgb=l9s+Y?37{ z^nM4=l+ICs#t^ST`+;57`}N!So*ODJ5JabUPKjjFFBclF8d(D2YmkMWqNS=T0XwjL zh2YW!IszhK>jLnRyg>i&ZMh2%2?+n}zeqq3XhU%6U+1U+zh{3Dz~`*ZU%!Nr9|(wn z|84>wkF<;bbv99d8sUF$1IGwtw4N#|0>4`3&K4H-F4hjNfmQw*z>ceq3i>Vt1T+uM zJ{J@<@2>;>58G(#x$3E^h?zS;xXoTWyt3f-fH (}g+1Jo6C@7~#k{{8pYeOh?f{P&gYUH&yJV1PVlM|d7{^YZ+=Z=k8f z* &!#V2ES#S@K!A(7 zO8)nR{p-5_dGKEiC3w!p{vWdVOVEGz0+N;_k>L6FtVxpae|72tCi0HWGj(m?7f`da zzl#gN*TcVlf$a-X6-Pg&PY4L42^62nXnR~(9w+)n|6-zT12)dUZv99$NNWsI)&luV zOXIHORB7SFu{zqKKjubT*
c1~QkiAlV^v*U*^^LD9DB{T8ULx% zq5C-ZXHwp6vJ024OB0;`b(1LJdKO#tI`hRV%zgytew7i(h|ym>_t2j |jWa@llQ&9s+8gAgnXtAOB&Z5@AwBeK_T%wOn1; zYH68vnoztv993<3GE080zTIS2C|P%#BwpakEMQ+56%@1><+prxn$v?^7;v$2Eaw^> zJ_&T|_Q?nfPkPhuc(fC%zfq{Wgli8I4`40}`vUchXUZznb)8e|gFS-mp~SRhuSU1_ zviK~=jkx`K++?TIHS6HDhHXGj_?~RXS zZcm!=!n 3(+8#yDatIaP+IEbt#;{IF^Bw67lfMY7#Byc zd^22aQHg3r?MHGg=gYGV>zb;C+ZOeNC^ZQnBz+RFLK>k9)VleP#505ACAao39UU$$ z^a*6V34bymO9Qco4d+0N &^qTESFJ-jqDENIWOz8TjpKm7@m+Jze(-9>m((qhf7s zc#bnIJrm~B<=vDjNGg+yGYux|uf?0K)r${(pa_oKez ~x>tTv zbJhE}fy!&H_|dLQ1%wRmqvM*!OozGISG!|xgI(_JrZEul@p-?69Dp;}MGuwZm=e7E z-2{A(?YvfhUfso4@@K5L#31Yk1QP6Bu;!`c=v)T@ma8k}>N%s+;VK_f4^FW0@xjO3 z70>yX1}!FT_>J!_TXPg?C-kdcEpK>w9*mMDxt>LPRcEn*l&rrkJQ+fm$+$ogIfTZQ zA{g9M+-zb;G$MR^C7*&Xe>}mheJ9tr4jQUEaW-+<$s~3|BG4V=sXQT#dk%F4SLdS^ zE5PrkzG3uBqJ4H3t|bbT 6`FRx*A2;)zGKE5w%8D8|RHIn{Crt!i$1`q=%njJOS} zrLGcm>iYIT{4`}YrMr6Qtv`Ryl4USwjFh#G!-iGrEeCZ;p+_!{yNf h;VyK9j|nk?KXJ*?8r4UloQ=v^>Qoa%B((JluaFMd?Wt* zV;FKOXT|w4S!E_yCZSA8t;mQa+KyGf32YF^H1rcaUJ5}^A5O0bvtqe~JH_`S`M-}5 zM^5A(e3)@M2MWL4B)y&$ixYv81YBCEo}34~QvO08$lVTD2_rfysSF ~1E!gmQIW8|PJUz@_J_rU;0W@8F&0{TgTt z*-Y~uUz3hfX=KJrF{zam@-QXFH -hJ|y7Hf`ZQ?hGp!FvZ^(bZ(>Q2j3nH z6R&caFxmHwU<{Kd7XH;QHbKczGTN^uflAy{*d0I0NICWmcL8CM##&3m>7PRHh;mqA z*@YBz*PMtB7ay%v&T?h&b7c5m1!b0#M<%rACAo}Vp+7X-Z5?E9pRiIX5uKl|w{J5Z z9f505tYy*ES&@+S Rt& }&fn4^*ZKv=(HgAq zn?mdlG8iWo)7LQMx+SOl>U8$?cmv8o)*Yc!Z1VJSHf(4+#`JZcrP~y>M#;`{=OEXs z;>sD4e(LpAs(>HhqH!VeY$;Dz5a_V?(h-RL?XS^de=kd}8n5FTha4=?TuA$!hrON> z`yacJ&( rX z#T0#CY-Q{>l#cP`LcJvimSyyVCwKpt Kd77Qyx_s&(v^OW>6G{arYtK)m8$aHYK@P+c9?H=N+No< zNLnB0gmrVx+^mCh%N)`eA`w0mi(jZ23v&)02jUs`NYDa0`o$L7ZrO(Dfcw;%sf j4S&G1kGJ9Dk+JKzm{*O+IB_A$%@% zUERB3jF|dns_QbZi-r8)(SC0x*tTD4@3p`Rv29NA_0ymw&({o`3iJ;BF1``);P)nP zp6+Ee*!px*^lydE&CO?gwMrG^?|%@<0xnH z&i8Ba-dN~224mlq#!s{{JGh>j<%w>$QP6=MX&0MJbv^Q1_}}9`?aDtUC!DDk2teOZ z-9aKORTG;nRJ6mZRkh8ltV(Fm1yDDK$*d7>0jg`JhV9J84>Wx7*{ljUc9Q-*#Vh>| zRrVn$ypC$mbj3}^1oa^f*g?QgjfIeSA*aS=kt;(10z*a%VXxk8dtb1YXq>E{OHHw+ z7}uq2E^t3hTk_JY$x}Oer15<<2cPRBHq7K+gnuc^yI3SOXBEM?J1@Dj3`aY(EHmTJ zV)b~oo~0chd+j#K tso{vB+rH<;C%%`=Ixp+M* zL?5Qnd$tmToGlAJ5*KhOoGwS@yS2!g^C>(2O#4j=i(yfaI{I>BcPkQwT&-*-{k-)KdiZP3#Q#>GwHznhoRmshW6>3aB3X0e%S^IhY{7}Z1< z*U5pGs;ph;g)L)H_*p8i)A58&Uf@O%Hv49EwgK*;Cq8=+)!v$wT?nMd$3+=KRipUA zFhbJyH>dbU+*Evv$m;KI WnJ&p&sn#V>=977sfTaIxV!p>V1MwVm5gXH$pWlTqn}y4 z=aju{;a~?f#;uauc#EpYosh=S5F%4;d64HHIPzOj5VWCdg2+z3Wt=8xmrdSp>h&ga z917kfG8wOEqFWPRLwCDPuvB^nEiR ?I3ClM)kvT&aGTSt3|g3v*6w;=BM+W}}U!>%RO XIzN6}y2B z3`1RO$mjNcraxNbNb^6#ZN}eh-SWZ@(ZTS=o;Y!N+HN~dtrQaqeZ7mby)5D*mlG>O zQ@2h@n-)R4whq{pu?D95j2Kl+Sh*r4xbes$V~HrqX`)eoz=h}A<}Z!i1sJ%xc&V|b z2A}T_sd;+TS!&+ai4?b|Gf(y9s|0&(H?mxIMM8ytth`|AHuT{UGEfQKChfUxhVwRd zacjy57A)W5S+EzA=4ZPXC+VXmgOPP)9lQ5;D}CjQE&wZQ>kwhd%pg&PJ+CBEr-iyM z2;!vJPR;c+vBdKAJ8k0HPUkL27Xmws##)%}ms80cmZtNsR8Yzd-%<6pSFU!<_JR)^ zN-6OCMmUSCeu0bn$M7lWrunogve+37vfvN_wDy+DJOdKdlVHlDg|^%A!R^&^045Nu zeK(zbIDfBN74jo|fdB2+6s`P}dO0iR?Pcoh_N%HgRoovIpSY9t!+o@t7=~0*sfNmR zL!mn{?vP@r!AM`*oae%U(&Ytz2PQC2y~r9tD0j*z`19=U00qBYiI4cG!P3m-Q~UUD zvgc@cT>Tk<#fV$kURwAmQ~jiWtB1~}$+zTD*Jr}mb-%?tCYL8}FAaj2jiU}bZnG>0 zu7UeUUg&^r*pgx #SIqc_RBWAVT{A^ z%;SdYW9Qs6JJ*>?3re4 Kq*1-jYL6#Q2OI$>idyk;4@ZPcCRq-khI)$) zwXpWNZbJLr31T~R$X;fYRf(mLb2FzFgA0brb q#X%I?spQ1O z8*oA>ogmM1-8WxaXdM`%Gi*{lK5OrJj-M^oZP+mYvE2rSize`pj75>QWTR1t%0R~5 zbM$fWjOJK%t96#Vn)js*z}?LcWNCsgY7))E^Ha8a^R|_=A ?EB>X?V#lSdQqL~v=x8s_@)@l_vN =M!!PV2wdBX(eV_CzNWcyctd0DaF-#Wc?*|eaa-uO63@ed^RPfE zU?2%i-gJ5%5K%d%c#eJiHup8ht#cz8(gp4B2>Swq)1j#%-))l#LolT@@2bw3&+B?= zfGeY&AL?nuusW){%KXrsHM#y(KHSpnXWA @pBb` 7r-xk8)Q(z%7del+@3sLVn&^7IQL?_?h)~$5H_lxvdx#{b7{?^04 z>pTEPeq7Np_ SA4&X| zp8X? 1!@n6sxLTAcNZv&k(8eGVL@fKup4Jw8n4M zU2%g&Zg_pF39>!kht7~C1!LgJJIf;jp4; GRiY zw9=O|PE(u{ti2`D0*rqU`iMg6_+_}%$+vv><>irb%DEzoju_ gA7K&f^h6c~ze`c%sDHN{N0oCr!viZ@ z9j`f}5S~8*@-GK8rGVg&-C|3_a`cebD9@dC;o*xL`?sx<%rfOd+YQk6 Ik?gO>yNM-IaZsY3LDJ%*-&mD=+iHn(K08w19@Rj^RHA&5nC*o45Uo0qGE-a~Q zzbm%UOgSAXEUGThORRJwt43BAf}ai(=jIS`>xtglMeR+LGr^7@b2nvbN=&zgmUju` z#&*YCdYsjS`0a<{G0r`4k6E_jR_D_ihjdMoU!1Tm_$Y*Ka|)fDQyf8K4d^fl+;^w@ zMQ^M&g)!|jBeMW%6$>#|^%Of6`LK|uKY6K)df&MQ%#+CYl+VPPO1hoRHxb6thAo*# zK{wQ!sJ7g)i;t+K?&;{A`FjYqWY };+57K4P7$$CCoKxD z)oz9P9B;Ha#fJd$qmAKiKiur#N#vF&AT6;+4Cy%WOyBu&`B=J+89(Vy5yr!}M59Wq zuT5wKs+YoVYaId0N@eC t;Hxf~vqHj$SLqV-r7@*|~mxMV! 3|{fk=x8gD0ercv(_+ zXxn|~+AZGigB+-coQbxU7=d^`iy#D`h7o }psXph zpaMo@=qdhJFc0!7CF^gMCl5@zrB08N+6EZ&mNugSBI+tVq;h2xp`17*CZ&sGHns}3 zKB-{HJ0?G`J~++k3>Z85us_p{V?@rx7 7<(PF zwTH%Yq7!09kCze c0Y354ckKTpewj>-8@XR6{h$LpXz(~^URQR zw(!V@GcxqlFZS|O^gcnhvlk8 F!5RujLJQ+kswi@$%h%*l?8Ai zhhN#Ri;bh%6fl?S@w d+t6lYg2(tNF3}G#5ja8g(bVB z_rQ&73`$H;V_CnjzzucL7`yfrwN=2iBV{W$Ulc Ny#tE81rO|J~AL%~~B$G*iRrL|*N>aFaM7;8M*emXC}{l0MZS z{PsZ3O+N15%5*vnxNh;aJL)`-)|E+a*FcwO_U!7G;5EMv2TnWypRq3@jXF78!Us+t zd99%;A%JZc4PUxIbiCMd$K?6WdJ{$E3I3?9L@|NZ*n6v$-a+L~E~9pj9Z|vQ$zHt{ z!`Kz=N=e+?fXWHa4o08tJ`a=e^{L`__%0!Ar`wp5Jb1hsy6-9j!w4&2o-umPr+ `Q|3VlNT%IX<6m(wz66c8i1~Rf1A2fvJrUk=A7u#mb+lUJ;4S^oM#MO7 zH<+jHhi3ucBR5)X@WjC*@CmOq(7*-%EXLClk#QdeqrL`Gx^rNKbQ3keGE7!$z4Y!D zoofc!4_H10c?@m2;de0MUe!5dODXiC&acN<^eY2|h{i~&n_{T=3goLVHuBUT^W7Pv z$||H?jkij<9eaC&SkE>;d%0pjZHuXW3^o(3yWBv`)OlPio-76p>iF`IQ&%}5wgO1& zpB{vd`|OQ7jf8q!B06?In2Ak{>2Wx-m<+e}kGFd8fm&-EzlXklpbb^^=^JBHzL8b9 zcd}B6OW_wCQqV1St&g@n0Ng+!r>cj}JE@W>9|l*kqvdkSj=C>mKsu(p=a;|GCVR!g z%XUGGk=Fd=wZQ+1A^*dgJP$ZCS0<0xKRE;HNIj@!P+s6?Kui1LcBHo|bYQ5^U 1fn))8>zsg&@$|y86ud@(bYV6oR -W3;P`;n{%L zZ)AZ*U1wYG2HyF_qv>7$MW&kEJAco+3`;5F*=;*@j>}AII5Rs9>|VfZO>5pTQ;e$6 zH}qOTKuS=%O3ML9J+PAjMz7_vq*#a2hRevGtclI2S{QyuSGhnQK7pD`b~n*cjLcdW zv-&+j$PGvqvh#!7Ypr0Ssy$_26;Vp oL-@`pdb9vW#DWh$>_sAWHu|talDWbg?wBOwD&y=tt=UxLH!7m7d0k= zOXBXUcQA^WhP%dt{C4c>S%jKq92ODqgj2- T@#sbNTrrO_&_j~T|Kk@YJU@= z5%(WK&c9|}x(Of-N+O{`uJh07B|IE8cCw)jE#=)}930y^ 2a+7zQFBFuQq%CXX%1YqxXoR{ajzaGKP+dJ0 |`rdm6mrW@rkqX zm?o-wXla;dC2~;91XVrcCB=!|tgOd#)m_P!vQL&NZDaJ>rx^0A*OocF%9a$N)dMOT zF^10!T)4#WavckpOM9=?s@&7(-FWe}T7Ggg#?S$kM7pY$A~9nBZR$gFIhQNyLiEK= z!$ Po8ouA9tQi51WHs~g5Y3B0;+jB7 zkE2`qq;~G>YTXV$3;29HnRdTusr|e lG**nD|=K)r{~#KL}1xjs$@NV?obHZGUu zOGJ>mbyRsn$@-fP$WBl8r^8nO5s@>6dEu4_0&z;Wv+8$8!8wGIW&`nLi=QWQ)l>IT z*BOnj2F^L07o>k+12QPtODa=epIGl$ +^R^(&8 zDVg6FjGnj!@^nRO;g9wzn<%6tw)8YTiqrJ(S`_LO^EJ)XWReyXm{j3}My*+}?l_<6 zz{p1LopscDBPst|q!*;W_PvZ}-RLBH)7K_)@oyT`u17l ;}2_Q1kH=s27XPnbGsU^ee9DSDI?dhp}~eEs}0Z z#B00V?@8Ne%D&QX0Y9KfR4UAC4l)ppErH8aw^!C4E*9p1iSq(s>BVC*)w9!pzYFcT z^~g2Fwe<%u&KND{oL&t7d32sM6kyqO+dLmyb5FodeQNN#SeFk&vd>=Z8LGZ5Zf_dQ z&Hqs4>0hIx;IZ;SwK`eAM$_okGt@FZ$7F30Rp`vYp8G4oGj6FdQxP>!8V^|dYE!jV z)k37U-9Rzk@py- %q~5t2dr4b)*8=k|N~_r=>|d={phUKiktuMlDn2?(=I!J#&MG20qAZm`&?s9- zVaR*#>jk^t2`QRUZ}6Bxp>Lk8G^0S=^Qu}T9~|%=V?XR&38 xXp8O;DaQ zmxcgrRn6ekeB&f7{wSa`xKS^l!0hAlUUPRyX^c3N?|%BiyL_{O0AA8Z;AxXwlb-=_ zD^!jopl%|Cgm)EDRnW;Nw0Y3tqz<6Y547;BB0*Pwi69)EueA4`*g~N5_)5PZ17fNv zFp=Eu=Nb?v7Qf-0IjuHw6tZwV_W>T>R3Kk5$L}E`I@FCOx>-4DTWH`v0=V0jlS54X zhs=*W*9tTr+B%?iV#pXJM67P@9IDkkwC*OYB__FAf@+{#^F77yxh-VJT7q&@=78|M zd}F%J3MA<`DQyT~xUY;ZFe)*gxfCz>nSEZh*eK=>D@bW*xiktynm hNbib{KHEH!z2o=>yy7o*tmWUMkrsopC#X$9Q=!kjZyFHEfLsF{pV4jAtae3IFb+ z2riPH(bkPiilD&2Yqwu53f8sKf&WDAKuqY$D&Sh4YtmW(gG-CqEr!BP7Hq3Urio~c zu9M#k*Sc$K@aC%VeJyCd`-nws5r&q|#0vFrih|)%Z-ZY&POyiqh_N1DKD8K+`#3Z< zAMQQ;x+plQK+bD;Fv?i43HrU^O~LPw?u*YARw~07#76;lbA2yw4=CSMPZkrD6qlym z({@;VWdK0PG=K812#g8V)$QFATfA0}i*e_RlB;tAsk3LqO4}WmkkjWznz=?Dxi|UD z93aVW9Vgz*S# - {k*U>OS%G7cd_J7E&+(2Y;Zd)w6)W+SfoNxOa+lwZ3!p01)}!Dg%6?9V$xCY#PC+ zo<)ATvpOy=$sFOzoNd$rObrGg27F@pE9vdOnR)kG|7!lUv6X0Foxig%z_!}u1B5%j zubs9@o%EgQQRnoijzi4~vJ <#U!Ec&%1KAaQd_Y(XWLF6K3 zR_=~70Q=OZ9Yt#=Eg`{%-OR=Vb$b(DE1|*@3Q1(q2+`jWPj9BWP_PD+AG~u#&E_Q9 ze?2{(lUki28vh_uZIYF8#2!!iAuk}LR8ywfwxN)1kH*mMbES4z;;A!ds;AXbV-A2} zoTC(Lp)%Dewa1$s)8#xji8 yD zk $tan*jiVB3}Bi4nb3C zQ&m6&Cmhe##;RP<$6LhbLd&z~f8On6r_`*~pVr~mV5h-6tO?qr#^w2>ui=2VM* X)2^EV%;yg}&Xs## zPW+(Bv_uu^k_TBnJ43oo3iOw!_~tPsrbcT *KQ|?a=VoF_V0EM2 zP=+qvfg$N3a)>4i%&>3~ahSXE#6n%0*yrbi*a}%1{jA}i7G$Q2KvbRF;7{B}+t`)x zd^^xKbLqP*Kxp!-FW}b!Y&i-r3yChq1YDIWFIZ)v^Uw|TVnYm7X{vMkqp|=-4yX++ z(XoMW0Ukcn?(Qc|%Q9|TSZtRJMgKGk|K7!NZu*Z*9kBQ9==gV40BPQQ>N=%_FYYx0 zB@EaG(tf=~5>BmI&|1+b9}r2xOZ{poBZpK8kdcA+bD13^^^>IxI7tn(emF;Ld-IN< zt@fR|!rfYlr5bopa=0^@Y5UB8tTB{VzOn#Q*L+hsYj;qm%XP#yaR^!9Xn^R4_BIKk zq^RtdK$&K*O=EZFTXj2&k(q$kZX3`YhcS5fxn;pd$*s?GQ=#&}ZEqAQ$DH$|&tJr9 z+BE=VTS!}cIj{Mjeg7AI(A7M3`mc8Z{2SQ+U-b7+ALrCooeAY1nf_Zf{%>{m-yQuU z(|?QNADRB|qWFJW9vxy_KLIY=y8d`GSkR`wS!npBf00wjZT?n(qdsj3Ka0H4W#(-~ za|bN--(jamrir{}@1Uz=BRW8K>6kD_A``l`(Z+=R@tLJqHkbwpP+C|zaM9<@po619 zfXR6^-4-5RNeW@gwx3~y< 7{55LWC z8OOPu46 IzxKARzV1UWU~U9o2P7m_G$L0vG>4g66YS2&-y> z_PWvb>Ns{32{Bw>N099Uln_?xWP<{XE{Y!qaE87=$Fnm|Xu3^JbcV{%b0NDtWiI^q zVyuz#Cp^INBO6ILhQGfhEWez@Zxyx>IRAu{>otRz>krRveEQDj8PO_G1THK_CNRAD z{dprbAfyQeH>w13bOAm<^88P>`4d};-saCQUdInor}#o0=X=x96*gK+eVOv{Ip3{s z C)Qtq*0*VEK&$6Pn?Y7Q` z51vl~Z}!BsrPuh1a{|bc=+t)~NI5}%MBLrj-aZ&8)GZMqSeih2bytiLn!@l<3FAHY zyOktEk#)q>n)t(|l8yR5xg5(rSz5${7`=>1i(X_VPVev F)ELi#8WR zEhSgVk&CqOkGBWk+V9lq4m2neeLc%u1Jw=ubIe#E$6#|9c7>v! $c*wWMxcZ01FPLu=p-S)3Uv04(d?#t!`K_I6Kmp`j{sx1!B+xK0pMEy zsFNbGPS_ntHet_*I>L}C;O%oLomAlEYe&Ui4_yiuewsz83jMs@wp3DYzc=n~YB~I5 z)ec~Z0Fl?sTq{UBD||pwNbWPwRi%KuM*HNMAP3|s52Z2Q5ASR1-9iS?nhaAZ!K-Ey zrnHWY{l3?q?C=b%;d*tj7$BK(GxdTV*4p*?(g%9`j}*J_o8Z-p1#Un_*%07E8*`mc z;5l!8##dcrQaDQDmY*#0r&*ji0f0c_1V?VFZ}m Xs?SCVNE~4Ncmb zhGxojS43S7`M6uWC?)uA`;eaRGQgLmrJs?M9%MIxFQP9tn+J^yD|Xg%Z_q{h8(*m3 z+0`A)>bpGlSbyoYR9yLsQIpol@$Dm(J;S@x>w!ENyfg7QV8E)3ltd?hLXh|;j|ERd z-fOD)1Jl-ZHf^)wI4g)Ck5<`Mj!D1Re8Fy@)NupA429QbK7T_L(7P%whx$pa2T*(^ zv=gJ?5{MXY?BJG;84Bi>@J=>VIsG&EP)%&9sNA_7MNOY|#vpBYf7@8pA*Nsgl7F2e zdSZrZ#AL727)Rg>b|vQFAfYndN^&`lH22E}zC>vD${gp{@J9+bfEyS~-GBhuQtwlM z8f)E}4_6q_{82E`4F@vctdip2@x{`nR`L1nZ-$S VxUi%_G&%L+bp`i6uqvpB1_%4tQPkTg=dAAgJ3oem>v%*mk zgi{S5B3|mLnn7`OK9sboX63%}57V^f4`HW!u$+{#!>%;P0|(fVVb0!Jbq|;xQlZi9 zL6s#16qq<25E0d~$EHEk_#TIYcJ*ejRcEc`0_J&cd!3AJeNan%1b}|@Qbliez!P9P zgH)1E?L8liu{#1-mcrzp5h`L{>UZ;UGIL6`h-r> nH%ne)~#&;s?+XB`APL-*`$Vw^b0yNiw{%KcFtf zP;UY{;sFTaq?C )T^Z8P z;3sGticU|cD<9$q<-ZuHz29Z}I6T`&E%u%QMyzix08aLK@JfG_b~~UBzUFUo^b*Q| zXTn-Pm;DK12G7WK4`s*nd^ft1+RgR@NnsnQk5~Ga>csjR8EBQPiNz$cjkUC|q)E$& z_W*d_ r}f#o swqO?^ zR~=^?z$Uoo1D}g*|NiK{jz}J}=Vw`(va=!uD*-yWnTL^!?uBiufOU>}bd o~cOdtN@(s1Vj} zS}wI}XfqXda 3>nvg7bd?b$X=-yDB;P^fm`YpFQL^&zm@Fq!8lWLHyd%s9 zRD}^hA(Ob*r9RUW2lMFLB+3sK_?5Gx2fYliUt41bIZz3+53KG6do!=NR0ByLa_I$r zRaIi#Sva?E=Vz7jhSfKO8Dts9b6T}_8-hI O4XMWCf#ov^hSUGyB)o0GBu4As(`_X)HeIw>wOpGF!`xL0Q|yfmRI zKdtfR&d><@_GPhwwBelp#ok*-Ro!iE!-62)AYFoVNJ)nv-O?=}A|L|N4bolG-5t`6 zgn-hmfTVP6YP)IPwY{J7Jm=i!d*1Q={f_g8V<2Pmi?!#PYtCz4^P14&`{+ZQUG0>< z*T-Kvz5K~<2euzUT5lu&8#m1B&U9TO&F0I!uW;#whV$AGAg>M(=b&S }WC+?*|>W?`T^M*dsV*hq1+rBG@O|oGhc-9320!%GJF8 z5E2-Xc7m$!WqOonwOs0i746uB{K$Ni^%Mt+=K77OU{BU}65C|{{rOnXkjZXN8{v92 zgu8V^D}}DS-d0&SdN(&!)AD;1 ;E6=p0kly6_xmd9 zCd|V5q{Z`Qc0&nKcj)cZ@5G1WZz3 Xq>i3U)dO9HqU}dH9r+l9EP<@`7nUf$FwC{eEI^Q2R5xm9pU&%JgsH{1I#W+s z9;w2mysk}CUYE!_a{1J|YR{yT2Y*-iwqVXic)I&u;v xBF?Tat|ee8io!iQk6{ zr&Y8svYi`7Ju3GH{ac9Fs>TG||1=y+I0NMp9k-5YK%J6C)f&=N<|Bcci4*JU=t){wk;b;5vq_;kN1bvyJ$t3R(u^k zg^Ai}S4tyMF8G>5T0`Zn$?$+ZfO4i(2ZuXzvK%Ajaf8=tbTAw_RW7z*4Rz`mCmh`6 zb>};9vziy$_)gu$fjtMZ2Dg*~hdx!eJ1be$+z&434I0%NUjRqywIbW6=Uy!DY5BCA zpD{*B6$`U&j|*&6r&Z72YKFLgvQw05FO0$H=;vj$$!WfEbeV0L`!w^FzPP>&baLuT z&&feXNbq}j^#U(Ou_OCTsM0dCvC^TG8FjX?8kS&vU~Q?mCnw4@v&Uvttaw@ii{I3k z8W*wlW?fMad(bf&B_60@`)Y1o!9Q* nMh*_qf&-n?>P)k){+cdKsNQe;%ME?;cRqa8Q17m02M2=;zkRT*wpZ{X z0qm1lTZ8vbM*}D`r|&*1-*NPSlb*?1t}13=vAY(mDbui^MxBm p6clN=#HwRvWd%LiJ22U=d6?)zF%pCimV& zCEA@IIdsSj8Dv9VCiYCYrisl#$)CNuq?-Dje{3y0{kyto`6axv>}3KOst=%?&mxks z@e+EuKDRyxVOG}Y!f9B7dY3>9Zp0=aLM=P|!FN70zYl!)O9^8-%b`Za4m)*{5XX_~ z&KM^en$n#LY|4)>1RudXS*-+8ziG2$`aoN9V99A!&vM2hy+&rfCT{^UM0SG+*u@u{ z;$H1l*;76%70VizSf$RT%O5>BTbB!Kr!8OPRs#Oirj+I0o6dUW9autIBhf+Awmw0b zE5y#=_I=Pom@zA7W@;WRCC!uiqcwF|3hbT8{cd09pIr(Ic9;z6TE3gC2k(#Wu%g5Q zhA-KEE;cR;UVOH(#W)!zAUL>!On3L~M_*b0p0f7D8v8>; G7A zl%;g;#XL?PoFZ^n*GMTaXRd%yvpKQMrI4>9aRI=WpWy4SJRf*7Un75-lV#hGC_AB& zTaHKmTWIoZai`;=s4}w&P5@=}n>*rIlt*WYA12!Tg`vB6cB9dk(7zfyRoOESFIEU& z->x5ay66+V4lE{b+iD=lwPN}>IVz#Ac%n*fJeFv7js9W!R1HC*vnbPs(oat4%?i0S zqns}*6Ha;sHmJC{S?)#)ABIZp+LPQ=rghC<%pUnnJ*{w#n~hhwnLWB#3Rran96MEt zR_3=V) `=16F9^A >L^XHYJ$Bx` zEuKhk-{5tMT!j7*o*SJ%KD=7Qsr=b|ZEz=<{7!eISV8stbh}Fi21>f~=XH-wGSBSY zU`^QLrO8cVT@g2nuEc}0TlpSaEFu``*leuBGhU_pVV&j)X^8riG}?+Roa+j9CCPPS zZA2ehidM8uYb13=tKSO*QDGkW^8DHxsfN6VcFr`WIDP&+67udQVz4YB;9CpPd_9Mu zoh#*&B@k+2cw4=0CN_4Xz0FK?r&*1jom1xj`O&? 6v%P8}mL`qwp9YP z*MRc&%xR=6ty2SFNngD3!+L#2n)KaVo`Xna3Hd0iWNfRR!YJl!9>67^rHMD8_igN+ z)*dFY$jw &Au6z;YUr(|^lk8JK$}_kZX}^)x(SdaY8;b6-*>XQz1AUe#p7j+Sqef- zG&-sd2XbYP55_@Gq4TCJ(^lC))UF|*$oTaxU#Xv3Zn=lJ4I>vO`{L;9+-I%*g;d(s z@3m9~4;J?%-&9!*7)@y?UeT6Qx*IJju1@yyRf%y1 PquU9KM6$GM##liPEQ~E-psnd6e8xG0gkC zmfM>e!dts~RnA4QRLQqcwHH%Y8bf6Vs(aEMXPO2&mV712jXk6dHN$>XQvy!tT^_;Z zmI<5c;Ix{b2{07Rt 4ia7*%Tg9pi(@?6ZEB*EHD?^BT zhbqy>wy`uozw5a@D;94_9_Y@HBx!h} N3hj+MQAw@;-|auU+^y34ofGu~tOI^FpNbh>U7S^Q4lRL`bHPp`*r z5Vi8&^^_XQy^nAyn#+S)--%&+3!$2k#}TjQqw;2aL$0AgQ&LBN!e>h`|8$x#kQJA+ z{sM(SGh#v9pfuKD8 a0Vke=&jR(pe5m5uIhs&oXMNXrxyxGOeIsW)OS!L z_s<9@eRT!Uynx4K#f_p+syWxZ*-wjSKPw@&wh&P4kCI!KzBDSj-*;&|XNR9i@dC${ z&lcy>5UokIl84=3{wYZe&86x>xmfbq!cHh%v^~y%W$3m Fb%4X9Bb zwE950ixH}7DRlwVeUgXn_UAlz0WuLWCOIu)li}gZ`rLKoj*Z!cx~vLf#D8#kXwtI$ z8fiymI+Dga3mFD@oBqhsaJG=mJn~M^aIlAi70PS_khj>)%%hYzAlYhrl5+K_D3kP{ zCP=vNonViF@0K|Ls>4+g=5Q8kTBtN9!lMR|8LPWttay*a^``{AK zM@hLqiM(=Mq$W{(7a|NLlM%fosx5y!v%t;^L_rEB<>v*V=`KoqcKTcLr<*wBOE7QE zM#+xJUSl70X6MiH%9i{kmaWUXb^EtxLoGgwLREWLUrdY-i5XWs9QSStYLr)X0Z7?Q z!^$o<_cYI5C)>(rYR}oD1KX`MX#J=cSJ{NGw|7h!nT3DRUdqr#W+6=SsW*R#)%7Lz z_?F+OmqYiP>sM#lAMA Kv^?sf7le5w47Mx zP>o~f{7Kz4R_!rk&;4#PV-&2J^`~zEd&Wl;UkJQKj;_OR-9@!vT_L#B)7Bb?x41F`>sk%^%EfS=>Opac1lXWt` z1SOYVZBTI9ZZdka&Cyuqu(yxi!9U}3xl?>j({;FarQJoDkha8gIeOg1^AqO3Zggaa63)NYqR};wzwX2boX$neEdu ztIE8@dCTq4WseY~dFiEo6kDwn++VbXfi^jXC~aGOc{}Y-Ny$6yDQOy||AGWx9Phdq zSFMnZSKQREJjZx7S6_EYT9g3PeV_t<>SKx{in{$$9b6!-ygi4aGxXM3qN7dz)DtVi zfQ%wV$fg`+D=0IoO;~0l{wRQa2cfG>F^wL|Z2Y&nz=WxjT~9+4I>OMsy1pMFy}NcZ zO*%2|mF4wC4ov%+)w4Ah*;nZMnhVBL+A&U DVNKNi zL0!IQsbx#EX=628Fp&Rb2^!=z24Jq%|AalWUCs2Q-iFT4o@MUOgCd jgg;Z)xV4HnBDO+7Hyi|xUNz3oQx$G#cd(>mg zX!RSkme?$vk?Uq_1W~*^-l8+)pv0U?1&v8T`nGc(C3|9;-b-!30$I*Fwhgp;Z@l;> znGarI*@U>mNiSqsfHfa9mx{4cf12)cOgHknxo!_)SbUSi=^W)GTl7R5q4h)1llqy` z>PxQDDOVyf!g S=Vu`vDAL!>BDTHxuuY#0oH ^Ah48Dz$nlO 5cnAN?o0M#hnmh_WPCZ5Pj@Mo*bPF=z=}Fej1=AUV+_ $AGd)Z!OEJz;(c=Rd(*}p3_T}4X0O+43t%K zn|d4*wKX)x+-_u0(>>H!m9+LKp;U=&zPM_8&xs{miEEUF@2$rebU70q?m22MLri1z z`77=gUN-%7iQqij&%&^C&cvxyZJ6)0 8D}T$lN88<5-OU;UhE-^ %923cx7?wGP{#}B8pPcBQ)e4U|OYMb4-g3MJ(AEj1@omp`U zJ<*1G^W %f6yZ{{=SvbENHC0aWmWIh z5_8{NR%Ksyn$&yMx1u#0FYaoUN0 Y(MG6b@k{>cX2Dn zc)3^aF;c$ygEMUH1J}®#<>BaZ0lo zGK z1P|ndOC^wmVlpYsoY=T^iG+$*loM1B5TY|0#m-}Kvd#^epy=0U{<4`jhKlAdi<^qx z9PtUMtyoWoSSkepKMVU=d}aE%d?4H^O_fqj{RzcW+qwCtPDycyzYElUCMJ*DIBUoE zSVd{ z{h{S {KCzz*yC&ZLg-BN4nVcZ412~hb1wV1>tuQ|4+jOpGvDrMqN zig79czx0-_qYK)`_V)66oX_pd7#sHKdSmkHOVIJ9QSn%o*Rs_u?`|!Q)*S3z>F;WE zZ_djhJuDd7WVtE(AL$o~bv(cjJ!*Zs{j7EQY9KRhzvsb$z+PVRDz-XV3-#NXM#uDr zzmguwxjKveyk@x`$1ZZ2zSaiR)2@Uv>eHa>*tzI(j=X}+?Al67fBS)MlS5u#Ux7Ox z=6+vL-c9@P7 pc){qQi^%fAQf*wHG5Ap<06(zAqp3rpWWKh9+ zW9L7dfzxQoNxwr(2MQ7jfw^nHABm=p77T xYgeF MVwQc?!^k9LXgLsRYcXE9`c!thkIj-tDjC#7o-l#WN zxw}wOZKih?A-<;6xGiZ+JRt{ovnbi20$9`1oas+@SZcn60ZO_d=cWCn(3PY`z;sW5 zwAEP9x`U<98;{HOBLlvX2yv5DZ~koPMFz(v&+JUjoTu_0lPx)?R&15Ute!JjcB82? z=D5o*{*jnb`|&T9MyJV&bD Lk8yFL aQk=PnyqKea<*R+j5wq#wgWJT8_tj=~ko98{jc+twNM^%5(+|l} n-P4m3i*$1^s?;Z3p8rgq~Qr+Msd|1x>OYQq=+VY;9a4)* >fHIG=ghqV%6eNyS`Q za_^jKSfV{f) d+@ix~x|JTm&tEru_Eo@s08!XQJ1x zc7uv&qb5%qj$hvGXCh}9eYxmD2| V9}Vu0lW?(VV0M z^I=utc%JR}BQ#nhW|i2NcOv)e?tav5Ep?Q;x}LUYj~%waG6Z=Xvjky-u1oGAR|v2v zg{7uYPteS%z3(RdD%jo8%tz0CX14GOZ%i5937&fqKWMb$)e0))<|z~>g(?E-_EaYo zeLPlr E^y85uVKND^+WQwhY)lo z#BXL0c;?m2#ku0Pm_#Zy?oP5FI?nMi*^`!b^YrLz1TAN2gOW_rTq?>G@9`MEA{(A) z#L2 kILH}G+f|4>b=1M1#KXspK6Wy;xjx!fNQl~` zI2~)jomd<{w!S_UIUPHQ^F5T;?HA+ZjDhIwr<873 `d-_=@h7K55oo!yV+xppHN)dZ zTO=8|daMg=%)=WZ?1N?3KvN Z{k=zbG*1hh2v5pJ9@b#|jpM=II27a_b9cwT5)0loKN#oSWg8R)So z+_9haS=7!&Kka)ivbSn7`&IEm1ZCo@U&*jwGD9f)l8sFz>(-MoA^{fM&XDD|wfcuB z1tX02+4~=l^ z8U&-7_4<**V%oDbMqtUY>maRYCw!2pF4k9kp!wiiZZ zS`|lyqE%B3#^x8wM^`tXAs|g@+pt9YdR|@9<5Pvx$SYCky5YdLXbf5Mr54nMz=_gt z1^F`-qRY8V#gleT9ZS{LH|*NNn;vg9 7ehd%lt(T_W#F%`_U*e*OO*pgC$H}Cq* zsl99exWd(E?^KZ===5#X;!($Q^;rehN < z4&0R|4M>ZtoGE0whmD2g72W7fzU$lHcr3`@d~_1Hk@eA?OsqJ0g!}eO{ROOXQ Klo%eQU zYmjCoO!=z~#plOB97lW!16OlMsOq$NV$rUpi?9Q~#fMhy{US3K<=EmFF3wQJL)y%n z6E$fI 6N)>Dr&~b zR+jV+Cv*puk9uOeeg_#-A~+AfY}Ip8-k*`|FBCWuFvTT%qQ?%qzpL &-c0tx!;=heb<=Lw+ zpyVnHe1U}j-tvghLYGcF+4^p9f<2S8{7z_#sjUH`Gjj8={FBOnVN9W _)rMofx8FT#@a*nVMpg8k;_c66buh()~%y4Pmt~at_~2 zvNkU^%agAX5Dfj#L)u>*`3++X0Ih|GAwIR@h)f^&oRv9aX8JNWsU!tmsP 0)*ii?t&;Vzx8U(D(W!+dQWg(ZMZrG#3}S=dQbDL4czyvgwA$D9TBPD)Y-f z@p$Z%)#qKzH7WEn29_iWXUTM&TNec#qL8x`VNZIr%W6>S1X_!hdCFvimYnRqY)v<6 zT`vX^RnBxe?UB7w=0jAn>v!Aj@>}Yz4<{Eq_A@8M>J<%qIe+CgMBkgUm(+e4=#r~} z?@#tDa}TKtud2bx%gjR3x^?!w_ok4<04+?Y5AC C{6kn0h-D@8BB}unn z!*vKX1a!&O`BCVn7BAfDmb=0<ZIF%dOUkCs-)ac-1-;6?7sq2Y}5SYR0&%p>$PW z* UjO&4PD^Z z_FmFz??ynEIyvT_a`j3fm`7i48sHfRx*)_|Is}M