Skip to content

Commit 1a6e5ea

Browse files
committed
Merge branch 'main' of https://github.com/MicrosoftDocs/azure-docs-pr into service-tag-patch
merge
2 parents 1db3acc + 76788de commit 1a6e5ea

21 files changed

+528
-495
lines changed

articles/aks/deploy-marketplace.md

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,19 @@ Included among these solutions are Kubernetes application-based container offers
2525

2626
This feature is currently supported only in the following regions:
2727

28+
- East US
29+
- West US
30+
- Central US
2831
- West Central US
32+
- South Central US
33+
- East US 2
34+
- West US 2
2935
- West Europe
30-
- East US
36+
- North Europe
37+
- Canada Central
38+
- Southeast Asia
39+
- Australia East
40+
- Central India
3141

3242
Kubernetes application-based container offers cannot be deployed on AKS for Azure Stack HCI or AKS Edge Essentials.
3343

@@ -44,14 +54,16 @@ az provider register --namespace Microsoft.KubernetesConfiguration --wait
4454

4555
1. In the [Azure portal](https://portal.azure.com/), search for **Marketplace** on the top search bar. In the results, under **Services**, select **Marketplace**.
4656

47-
1. You can search for an offer or publisher directly by name, or you can browse all offers. To find Kubernetes application offers, use the **Product Type** filter for **Azure Containers**.
57+
1. You can search for an offer or publisher directly by name, or you can browse all offers. To find Kubernetes application offers, on the left side under **Categories** select **Containers**.
4858

49-
:::image type="content" source="./media/deploy-marketplace/browse-marketplace-inline.png" alt-text="Screenshot of Azure Marketplace offers in the Azure portal, with the filter for product type set to Azure containers." lightbox="./media/deploy-marketplace/browse-marketplace-full.png":::
59+
:::image type="content" source="./media/deploy-marketplace/containers-inline.png" alt-text="Screenshot of Azure Marketplace offers in the Azure portal, with the container category on the left side highlighted." lightbox="./media/deploy-marketplace/containers.png":::
5060

5161
> [!IMPORTANT]
52-
> The **Azure Containers** category includes both Kubernetes applications and standalone container images. This walkthrough is specific to Kubernetes applications. If you find that the steps to deploy an offer differ in some way, you're most likely trying to deploy a container image-based offer instead of a Kubernetes application-based offer.
53-
>
54-
> To ensure that you're searching for Kubernetes applications, include the term **KubernetesApps** in your search.
62+
> The **Containers** category includes both Kubernetes applications and standalone container images. This walkthrough is specific to Kubernetes applications. If you find that the steps to deploy an offer differ in some way, you're most likely trying to deploy a container image-based offer instead of a Kubernetes application-based offer.
63+
64+
1. You will see several Kubernetes application offers displayed on the page. To view all of the Kubernetes application offers, select **See more**.
65+
66+
:::image type="content" source="./media/deploy-marketplace/see-more-inline.png" alt-text="Screenshot of Azure Marketplace K8s offers in the Azure portal" lightbox="./media/deploy-marketplace/see-more.png":::
5567

5668
1. After you decide on an application, select the offer.
5769

Binary file not shown.
Binary file not shown.
345 KB
Loading
345 KB
Loading
334 KB
Loading
334 KB
Loading

articles/mysql/.openpublishing.redirection.mysql.json

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,6 @@
6565
"redirect_url": "/azure/mysql/single-server/tutorial-provision-mysql-server-using-azure-resource-manager-templates",
6666
"redirect_document_id": false
6767
},
68-
{
69-
"source_path_from_root": "/articles/mysql/app-development-best-practices.md",
70-
"redirect_url": "/azure/mysql/single-server/app-development-best-practices",
71-
"redirect_document_id": false
72-
},
7368
{
7469
"source_path_from_root": "/articles/mysql/concept-monitoring-best-practices.md",
7570
"redirect_url": "/azure/mysql/single-server/concept-monitoring-best-practices",
@@ -426,9 +421,9 @@
426421
"redirect_document_id": false
427422
},
428423
{
429-
"source_path_from_root": "/articles/mysql/howto-create-users.md",
430-
"redirect_url": "/azure/mysql/single-server/how-to-create-users",
431-
"redirect_document_id": false
424+
"source_path_from_root": "/articles/mysql/howto-create-users.md",
425+
"redirect_url": "/azure/mysql/single-server/how-to-create-users",
426+
"redirect_document_id": false
432427
},
433428
{
434429
"source_path_from_root": "/articles/mysql/howto-data-encryption-cli.md",
@@ -705,11 +700,6 @@
705700
"redirect_url": "/azure/mysql/single-server/security-controls-policy",
706701
"redirect_document_id": false
707702
},
708-
{
709-
"source_path_from_root": "/articles/mysql/select-right-deployment-type.md",
710-
"redirect_url": "/azure/mysql/single-server/select-right-deployment-type",
711-
"redirect_document_id": false
712-
},
713703
{
714704
"source_path_from_root": "/articles/mysql/single-server-overview.md",
715705
"redirect_url": "/azure/mysql/single-server/single-server-overview",
@@ -779,6 +769,21 @@
779769
"source_path_from_root": "/articles/mysql/single-server/quickstart-create-mysql-server-database-using-azure-portal.md",
780770
"redirect_url": "/azure/mysql/flexible-server/quickstart-create-server-portal",
781771
"redirect_document_id": false
772+
},
773+
{
774+
"source_path_from_root": "/articles/mysql/single-server/how-to-create-users.md",
775+
"redirect_url": "/azure/mysql/how-to-create-users",
776+
"redirect_document_id": true
777+
},
778+
{
779+
"source_path_from_root": "/articles/mysql/single-server/app-development-best-practices.md",
780+
"redirect_url": "/azure/mysql/app-development-best-practices",
781+
"redirect_document_id": true
782+
},
783+
{
784+
"source_path_from_root": "/articles/mysql/single-server/select-right-deployment-type.md",
785+
"redirect_url": "/azure/mysql/select-right-deployment-type",
786+
"redirect_document_id": true
782787
}
783788
]
784789
}

articles/mysql/TOC.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@
77
href: single-server/overview.md
88
- name: Select the right MySQL deployment type
99
href: single-server/select-right-deployment-type.md
10-
- name: What's new in Single Server?
11-
href: single-server/single-server-whats-new.md
12-
- name: What's new in Flexible Server?
13-
href: flexible-server/whats-new.md
1410
- name: Try Flexible Server for free
1511
href: flexible-server/how-to-deploy-on-azure-free-account.md
1612
- name: Prepay for reserved capacity
@@ -24,6 +20,8 @@
2420
items:
2521
- name: What is Flexible Server?
2622
href: flexible-server/overview.md
23+
- name: What's new in Flexible Server?
24+
href: flexible-server/whats-new.md
2725
- name: Compute and storage
2826
href: flexible-server/concepts-compute-storage.md
2927
- name: Quickstarts
@@ -320,6 +318,8 @@
320318
items:
321319
- name: What is Single Server?
322320
href: single-server/single-server-overview.md
321+
- name: What's new in Single Server?
322+
href: single-server/single-server-whats-new.md
323323
- name: Pricing Tiers
324324
items:
325325
- name: Pricing tiers
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
---
2+
title: App development best practices - Azure Database for MySQL
3+
description: Learn about best practices for building an app by using Azure Database for MySQL.
4+
author: mksuni
5+
ms.author: sumuth
6+
ms.reviewer: maghan
7+
ms.date: 03/29/2023
8+
ms.service: mysql
9+
ms.subservice: single-server
10+
ms.topic: conceptual
11+
---
12+
13+
# Best practices for building an application with Azure Database for MySQL
14+
15+
[!INCLUDE [applies-to-mysql-single-flexible-server](includes/applies-to-mysql-single-flexible-server.md)]
16+
17+
[!INCLUDE [azure-database-for-mysql-single-server-deprecation](includes/Azure-database-for-mysql-single-server-deprecation.md)]
18+
19+
Here are some best practices to help you build a cloud-ready application using Azure Database for MySQL. These best practices can reduce the development time for your app.
20+
21+
## Configuration of application and database resources
22+
23+
### Keep the application and database in the same region
24+
25+
Ensure all your dependencies are in the same region when deploying your application in Azure. Spreading instances across regions or availability zones creates network latency, which might affect the overall performance of your application.
26+
27+
### Keep your MySQL server secure
28+
29+
Configure your MySQL server to be [secure](single-server/concepts-security.md) and not accessible publicly. Use one of these options to secure your server:
30+
31+
- [Firewall rules](single-server/concepts-firewall-rules.md)
32+
- [Virtual networks](single-server/concepts-data-access-and-security-vnet.md)
33+
- [Azure Private Link](single-server/concepts-data-access-security-private-link.md)
34+
35+
For security, you must always connect to your MySQL server over SSL and configure your MySQL server and your application to use TLS 1.2. See [How to configure SSL/TLS](single-server/concepts-ssl-connection-security.md).
36+
37+
### Use advanced networking with AKS
38+
39+
When accelerated networking is enabled on a VM, there's lower latency, reduced jitter, and decreased CPU utilization on the VM. To learn more, see [Best practices for Azure Kubernetes Service and Azure Database for MySQL](single-server/concepts-aks.md).
40+
41+
### Tune your server parameters
42+
43+
For read-heavy workloads tuning server parameters, `tmp_table_size` and `max_heap_table_size` can help optimize for better performance. To calculate the values required for these variables, look at the total per-connection and base memory values. The sum of per-connection memory parameters, excluding `tmp_table_size`, combined with the base memory accounts for total memory of the server.
44+
45+
To calculate the largest possible size of `tmp_table_size` and `max_heap_table_size`, use the following formula:
46+
47+
`(total memory - (base memory + (sum of per-connection memory * # of connections)) / # of connections`
48+
49+
> [!NOTE]
50+
> Total memory indicates the total amount of memory that the server has across the provisioned vCores. For example, in a General Purpose two-vCore Azure Database for MySQL server, the total memory will be 5 GB * 2. You can find more details about memory for each tier in the [pricing tier](single-server/concepts-pricing-tiers.md) documentation.
51+
>
52+
> Base memory indicates the memory variables, like `query_cache_size` and `innodb_buffer_pool_size`, that MySQL will initialize and allocate at the server start. Per-connection memory, like `sort_buffer_size` and `join_buffer_size`, is the memory allocated only when a query needs it.
53+
54+
### Create nonadmin users
55+
56+
[Create nonadmin users](how-to-create-users.md) for each database. Typically, the user names are identified as the database names.
57+
58+
### Reset your password
59+
60+
You can [reset your password](single-server/how-to-create-manage-server-portal.md#update-admin-password) for your MySQL server using the Azure portal.
61+
62+
Resetting your server password for a production database can bring down your application. It's a good practice to reset the password for any production workloads at off-peak hours to minimize the impact on your application's users.
63+
64+
## Performance and resiliency
65+
66+
Here are a few tools and practices to help debug your application's performance issues.
67+
68+
### Enable slow query logs to identify performance issues
69+
70+
You can enable [slow query logs](single-server/concepts-server-logs.md) and [audit logs](single-server/concepts-audit-logs.md) on your server. Analyzing slow query logs can help identify performance bottlenecks for troubleshooting.
71+
72+
Audit logs are also available through Azure Diagnostics logs in Azure Monitor logs, Azure Event Hubs, and storage accounts. See [How to troubleshoot query performance issues](single-server/how-to-troubleshoot-query-performance.md).
73+
74+
### Use connection pooling
75+
76+
Managing database connections can have a significant impact on the performance of the application as a whole. To optimize performance, you must reduce the number of times connections are established and the time for establishing connections in key code paths. Use [connection pooling](single-server/concepts-connectivity.md#access-databases-by-using-connection-pooling-recommended) to connect to Azure Database for MySQL to improve resiliency and performance.
77+
78+
You can use the [ProxySQL](https://proxysql.com/) connection pooler to manage connections efficiently. Using a connection pooler can decrease idle connections and reuse existing connections, which helps avoid problems. See [How to set up ProxySQL](https://techcommunity.microsoft.com/t5/azure-database-for-mysql/connecting-efficiently-to-azure-database-for-mysql-with-proxysql/ba-p/1279842) to learn more.
79+
80+
### Retry logic to handle transient errors
81+
82+
Your application might experience [transient errors](single-server/concepts-connectivity.md#handling-transient-errors) where connections to the database are dropped or lost intermittently. In such situations, the server is up and running after one to two retries in 5 to 10 seconds.
83+
84+
A good practice is to wait for 5 seconds before your first retry. Then follow each retry by increasing the wait gradually, up to 60 seconds. Limit the maximum number of retries, at which point your application considers the operation failed, so you can further investigate. See [How to troubleshoot connection errors](single-server/how-to-troubleshoot-common-connection-issues.md) to learn more.
85+
86+
### Enable read replication to mitigate failovers
87+
88+
For failover scenarios, you can use [Data-in Replication](single-server/how-to-data-in-replication.md). No automated failover between source and replica servers occurs when using read replicas.
89+
90+
You notice a lag between the source and the replica because the replication is asynchronous. Network lag can be influenced by many factors, like the size of the workload running on the source server and the latency between data centers. In most cases, replica lag ranges from a few seconds to a few minutes.
91+
92+
## Database deployment
93+
94+
### Configure an Azure database for MySQL task in your CI/CD deployment pipeline
95+
96+
Occasionally, you need to deploy changes to your database. In such cases, you can use continuous integration (CI) and continuous delivery (CD) through [Azure Pipelines](https://azure.microsoft.com/services/devops/pipelines/) and use a task for [your MySQL server](/azure/devops/pipelines/tasks/deploy/azure-mysql-deployment) to update the database by running a custom script against it.
97+
98+
### Use an effective process for manual database deployment
99+
100+
During manual database deployment, follow these steps to minimize downtime or reduce the risk of failed deployment:
101+
102+
1. Create a copy of a production database on a new database by using [mysqldump](https://dev.mysql.com/doc/refman/8.0/en/mysqldump.html) or [MySQL Workbench](https://dev.mysql.com/doc/workbench/en/wb-admin-export-import-management.html).
103+
1. Update the new database with your new schema changes or updates needed for your database.
104+
1. Put the production database in a read-only state. It would be best if you didn't have write operations on the production database until deployment is completed.
105+
1. Test your application with the newly updated database from step 1.
106+
1. Deploy your application changes and make sure the application is now using the new database with the latest updates.
107+
1. Keep the old production database to roll back the changes. You can then evaluate to delete the old production database or export it on Azure Storage if needed.
108+
109+
> [!NOTE]
110+
> If the application is like an e-commerce app and you can't put it in a read-only state, deploy the changes directly on the production database after making a backup. These changes should occur during off-peak hours with low traffic to the app to minimize the impact because some users might experience failed requests.
111+
>
112+
> Make sure your application code also handles any failed requests.
113+
114+
### Use MySQL native metrics to see if your workload is exceeding in-memory temporary table sizes
115+
116+
With a read-heavy workload, queries against your MySQL server might exceed the in-memory temporary table sizes. A read-heavy workload can cause your server to switch to writing temporary tables to disk, affecting your application's performance. To determine if your server is writing to disk as a result of exceeding temporary table size, look at the following metrics:
117+
118+
```sql
119+
show global status like 'created_tmp_disk_tables';
120+
show global status like 'created_tmp_tables';
121+
```
122+
123+
The `created_tmp_disk_tables` metric indicates how many tables were created on disk. Given your workload, the `created_tmp_table` metric tells you how many temporary tables must be formed in memory. To determine if a specific query uses temporary tables, run the [EXPLAIN](https://dev.mysql.com/doc/refman/8.0/en/explain.html) statement on the query. The detail in the `extra` column indicates `Using temporary` if the query runs using temporary tables.
124+
125+
To calculate the percentage of your workload with queries spilling to disks, use your metric values in the following formula:
126+
127+
`(created_tmp_disk_tables / (created_tmp_disk_tables + created_tmp_tables)) * 100`
128+
129+
Ideally, this percentage should be less than 25%. If the percentage is 25% or greater, we suggest modifying two server parameters, tmp_table_size, and max_heap_table_size.
130+
131+
## Database schema and queries
132+
133+
Here are a few tips to remember when building your database schema and queries.
134+
135+
### Use the correct datatype for your table columns
136+
137+
Using the correct datatype based on the type of data you want to store can optimize storage and reduce errors due to incorrect datatypes.
138+
139+
### Use indexes
140+
141+
To avoid slow queries, you can use indexes. Indexes can help find rows with specific columns quickly. See [How to use indexes in MySQL](https://dev.mysql.com/doc/refman/8.0/en/mysql-indexes.html).
142+
143+
### Use EXPLAIN for your SELECT queries
144+
145+
Use the `EXPLAIN` statement to get insights on what MySQL is doing to run your query. It can help you detect bottlenecks or issues with your query. See [How to use EXPLAIN to profile query performance](single-server/how-to-troubleshoot-query-performance.md).

0 commit comments

Comments
 (0)